DEV Community

Cover image for A month of Flutter: Stream transforms and failing tests
Abraham Williams
Abraham Williams

Posted on • Originally published at bendyworks.com

4 1

A month of Flutter: Stream transforms and failing tests

Originally published on bendyworks.com.

Now that I've got a Post model with mock data and a StreamBuilder for rendering, it all needs to be wired together.

The main changes I'm making are in _MyHomePageState where I'm replacing the stream of ints with a call to the new _loadPosts method.

Stream<List<Post>> _loadPosts(BuildContext context) {
  return DefaultAssetBundle.of(context)
      .loadString('assets/posts.json')
      .then<List<dynamic>>((String value) => json.decode(value))
      .asStream()
      .map(_convertToPosts);
}
~~~{% endraw %}

{% raw %}`_loadPosts`{% endraw %} uses [{% raw %}`DefaultAssetBundle.of`{% endraw %}](https://docs.flutter.io/flutter/widgets/DefaultAssetBundle/of.html) to get the most appropriate [{% raw %}`AssetBundle`](https://docs.flutter.io/flutter/services/AssetBundle-class.html) for loading files from the `assets` directory.

Reading the {% raw %}`String`{% endraw %} contents of a file is asynchronous, after which the JSON contents can be decoded. The loading and decoding will happen as a {% raw %}`Future`{% endraw %} but I want to be working on a stream so I'll use [`asStream`](https://api.dartlang.org/stable/2.1.0/dart-async/Future/asStream.html) to convert the `Future` to a `Stream`.

Finally the Stream will then get transformed using [`map`](https://api.dartlang.org/stable/2.1.0/dart-async/Stream/map.html) and another new method `_convertToPosts`.

~~~dart
List<Post> _convertToPosts(List<dynamic> data) {
  return data.map((dynamic item) => Post.fromMap(item)).toList();
}
~~~

Every time an event comes down the stream, `map` will call the convert method on the value. In this case the value is a `List` of items and `List`'s [{% raw %}`map`{% endraw %}](https://api.dartlang.org/stable/2.1.0/dart-core/Iterable/map.html) will pass each item to `Post.fromMap`. Note that `map` on a `List` is different from `map` on a `Stream`. `map` on a `List` is lazy so we'll force it to execute with a final [`toList`](https://api.dartlang.org/stable/2.1.0/dart-core/Iterable/toList.html).

The rest of the changes are going thought the code base and updating {% raw %}`List<int>`{% endraw %} types to be {% raw %}`List<Post>`{% endraw %} types and passing {% raw %}`Post`{% endraw %} instances into the rendering {% raw %}`PostItem`{% endraw %}s. I'll also replace the hard coded `'Prim Birb'` text with the dynamic `username` from the `Post` instances.

![Screenshot of rendered mock usernames](https://thepracticaldev.s3.amazonaws.com/i/lmfoehbinrds1zn7kvaw.png)

As I was updating the tests to use the new mock JSON data, I kept running into failures. I was seeing tests timing out or the `PostsList` error handling showing errors instead of content. After some digging it turns out that the code in `testWidgets` [can't access](https://github.com/flutter/flutter/issues/8490) files or assets. With [CI configured](https://bendyworks.com/blog/a-month-of-flutter-configuring-continuous-integration) I can't merge code without passing tests so come back tomorrow to see how I fix them.

## Code changes

- [#29 Turn mock posts into Stream](https://github.com/abraham/birb/pull/29)
Enter fullscreen mode Exit fullscreen mode

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay