0

Imagine a very simple application with two pages, PostList and PostDetail. On the former page, we show a list of posts, and on the latter, the details of a single post.

Now consider the following scenario. Our user clicks on the first PostItem and navigates to the PostDetail page. We fetch the full post data from the server. The likes_count of this post gets increased by one. Now if our user navigates back to the first page, the PostItem should be updated and show the new likes_count as well.

One possible solution to handle this is to create a pool of posts. Now when we fetch some new data from the server, instead of creating a new post object, we can update our corresponding pool instance object. For example, if we navigate to post with id=3, we can do something like this:

Post oldPost = PostPool.get(3)
oldPost.updateFromJson(servers_new_json_for_post_3)

Since the same object is used on the PostDetail page, our PostItem on the PostList page will be updated as well.

Other approaches that do not use a unique "single instance" of our Post objects, across the application, would not be clean to implement and requires tricks to keep the UI sync.

But the ObjectPool approach also has its own problems and leads to memory leaks since the size of the pool gets bigger and bigger over time. For this problem to get solved we need to manually count the number of references for each pool object instance and discard them when this count is equal to zero. This manual calculation is full of bugs and I was wondering if there are any better ways to achieve this.

Emad Hedayati
  • 94
  • 2
  • 8

1 Answers1

1

You can also solve this by using streams and StreamBuilders. First you create the stream and populates it with the initial data fetched from the API: I like to use BehaviorSubject from rxdart but you can use normal streams too.

final BehaviorSubject<List<Post>> postsStream = BehaviorSubject<List<Post>>()..startWith(<Post>[]);

On the constructor body or initState function you would fetch the data and add it to the stream.

PostPage() {
  _fetchPosts().then((posts) => postsStream.add(posts));
}

You can now subscribe to changes on this postsStream in both pages with StreamBuilder. Any update you need to do you would emit a new (updated) List<Post> to the stream triggering a rebuild on any StreamBuilder subscribed to the stream with the new and updated values.

You can latter dispose the StreamController.

pedro pimont
  • 2,764
  • 1
  • 11
  • 24
  • Hi Pedro, thank you so much for your thorough answer. Yeah, I'm familiar with this concept and I know that your approach will actually lead to a synced UI. But my question still remains. I want to have a single Post object (for each post_id) across the entire application. And of course, a way to solve the stated memory leaks problem. – Emad Hedayati Jul 20 '21 at 11:57
  • Hi @EmadHedayati , sorry for not being able to help you more. I'm not familiar with this ObjectPool pattern, but it got me interested. Hope you find a more suitable solution soon and tell us. – pedro pimont Jul 20 '21 at 13:05
  • No problem! Your answer was useful actually and I learned something new from it. – Emad Hedayati Jul 20 '21 at 13:16