Skip to content

replaceMore() assertion error suggests _insertComment operating on an existing comment #180

Open
@inhumantsar

Description

@inhumantsar

so i've got a stateless ListView based widget filled by a viewmodel and a singleton service. when i scroll to the end of the ListView, the widget successfully relays a call to replaceMore() and those new comments pop in to the ListView.

When I scroll to the new bottom and encounter the second MoreComments object, I get an exception. The assertion it fails on suggests to that the insert is being called on a Comment which already exists in the Submission's comment list.

Not sure if this is a bug or pebkac. I don't see how replaceMore could run into a comment that already exists if i'm awaiting it between calls.

[RedditService] loading discussion thread...
[RedditService] found dt: https://redd.itgt9vt5
[RedditService] dt populated: Discussion Thread (75 comments)
... scroll to bottom ...
[DtViewModel] found morecomments: fsab9qd
[RedditService] asked to replace MoreComments objs.  status: false currentDt.comments.length=75
[RedditService] replacement complete. status: false currentDt.comments.length=84
... scroll to new bottom ...
[DtViewModel] found morecomments: fsabd63
[RedditService] asked to replace MoreComments objs.  status: false currentDt.comments.length=84
[RedditService] 'package:draw/src/models/comment_forest.dart': Failed assertion: line 41 pos 12: '(comment is MoreComments) ||
                        ((comment…
// widget
...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('DT'),
        backgroundColor: Colors.amber,
      ),
      body: ListView.builder(
        itemCount: this.vm.dt?.comments?.length ?? 0,
        shrinkWrap: true,
        itemBuilder: (context, index){
          if (this.vm.dt?.comments == null) return const SizedBox.shrink();
          if (this.vm.dt.comments.length <= index) return const SizedBox.shrink();
          var rawcomm = this.vm.dt.comments[index];
          if (rawcomm == null) return SizedBox.shrink();
          if (rawcomm is MoreComments) {
            this.vm.log.v('found morecomments: ${rawcomm.id}');
            this.vm.replaceMoreComments();
            return const SizedBox.shrink();
          }
          return CommentCardWidget(TacoComment.fromComment(rawcomm));
        },
      )
  }
}
// viewmodel extends ChangeNotifier
...
  Submission get dt => this.service.currentDt;
...
  void replaceMoreComments() => this.service.replaceMoreComments().whenComplete(() => this.notifyListeners());
...
// service singleton
  ...
  Future<void> replaceMoreComments() async {
    if (this.replacingMoreComments == false) {
      this.log.v('asked to replace MoreComments objs.  status: ${this.replacingMoreComments} currentDt.comments.length=${this.currentDt.comments.length}');
      this.replacingMoreComments = true;
      try {
        await this.currentDt.comments.replaceMore();
      } catch(e) {
        this.log.e(e.toString());
      }
      this.replacingMoreComments = false;
      this.log.v('replacement complete. status: ${this.replacingMoreComments} currentDt.comments.length=${this.currentDt.comments.length}');
    } else this.log.v('skipping replace, status: ${this.replacingMoreComments}');
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions