Reader small image

You're reading from  Flutter Cookbook, Second Edition - Second Edition

Product typeBook
Published inMay 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781803245430
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
Simone Alessandria
Simone Alessandria
author image
Simone Alessandria

Simone Alessandria wrote his first program when he was 12. It was a text-based fantasy game for the Commodore 64. Now, he is a trainer (MCT), author, speaker, passionate software architect, and always a proud coder. He is the founder and owner of Softwarehouseit. His mission is to help developers achieve more through training and mentoring. He has authored several books on Flutter, including Flutter Projects, published by Packt, and web courses on Pluralsight and Udemy.
Read more about Simone Alessandria

Right arrow

Advanced State Management with Streams

In Dart and Flutter, futures and streams are the main tools to deal with asynchronous programming.

While Future represents a single value that will be delivered at a later time in the future, Stream is a set (sequence) of values (0 or more) that can be delivered asynchronously, at any time. Basically, it is a flow of continuous data.

In order to get data from a stream, you subscribe (or listen) to it. Each time some data is emitted, you can receive and manipulate it as required by the logic of your app.

By default, each stream allows only a single subscription, but you will also see how to enable multiple subscriptions.

This chapter focuses on several use cases of streams in a Flutter app. You will see streams used in different scenarios, and how to read and write data to streams, build user interfaces based on streams, and use the BLoC state management pattern.

Like futures, streams can generate data or errors...

Technical requirements

To follow along with the recipes in this chapter, you should have the following software installed on your Windows, Mac, Linux, or ChromeOS device:

  • The Flutter SDK
  • The Android SDK when developing for Android
  • macOS and Xcode when developing for iOS
  • An emulator or simulator, or a connected mobile device enabled for debugging
  • Your favorite code editor: Android Studio, Visual Studio Code, and IntelliJ IDEA are recommended; all should have the Flutter/Dart extensions installed

You’ll find the code for the recipes in this chapter on GitHub at https://github.com/PacktPublishing/Flutter-Cookbook-Second-Edition/tree/main/Chapter_10.

How to use Dart streams

In this recipe’s demo, you will change the background color of a screen each second. You will create a list of five colors, and every second you will change the background color of a Container widget that fills the whole screen.

The color information will be emitted from a Stream of data. The main screen will need to listen to the Stream to get the current Color, and update the background accordingly.

While changing a color isn’t exactly something that strictly requires a Stream, the principles explained here may apply to more complex scenarios, including getting flows of data from a web service. For instance, you could write a chat app that updates the content based on what users write in real time, or an app that shows stock prices in real time.

Getting ready

In order to follow along with this recipe, you can download the starting code for the project at https://github.com/PacktPublishing/Flutter-Cookbook-Second-Edition/tree...

Using stream controllers and sinks

StreamControllers create a linked Stream and Sink. While streams contain data emitted sequentially that can be received by any subscriber, sinks are used to insert events.

StreamControllers simplify stream management, automatically creating a stream and a sink, and methods to control their events and features.

In this recipe, you will create a stream controller to listen to and insert new events. This will show you how to fully control a stream.

Getting ready

In order to follow along with this recipe, you should have completed the code in the previous recipe, How to use Dart streams.

How to do it...

For this recipe, we will make our app display a random number on the screen, leveraging StreamControllers and their sink property:

  1. In the stream.dart file, import the dart:async library:
    import 'dart:async';
    
  2. At the bottom of the stream.dart file, add a new class, called NumberStream...

Injecting data transforms into streams

A rather common scenario is the need to manipulate and transform data emitted from a stream before it gets to its final destination.

This is extremely useful when you want to filter data based on any type of condition, validate it, modify it before showing it to your users, or process it to generate some new output.

Examples include converting a number into a string, making a calculation, or omitting data repetitions.

In this recipe, you will inject StreamTransformers into Streams in order to map and filter data.

Getting ready

In order to follow along with this recipe, you should have completed the code in the previous recipe, Using stream controllers and sinks.

How to do it...

For this recipe, you will edit the random number on the screen, leveraging a StreamTransformer, starting from the code that you completed in the previous recipe, Using stream controllers and sinks:

  1. At the top of the _StreamHomePageState...

Subscribing to stream events

In the previous recipes of this chapter, we used the listen method to get values from a stream. This generates a Subscription. Subscriptions contain methods that allow you to listen to events from streams in a structured way.

In this recipe, we will use Subscription to gracefully handle events and errors, and close the subscription.

Getting ready

In order to follow along with this recipe, you should have completed the code in the previous recipe, Injecting data transforms into streams.

How to do it...

For this recipe, we will use a StreamSubscription with its methods. We will also add a button to close the stream. Perform the following steps:

  1. At the top of the _StreamHomePageState class, declare a StreamSubscription called subscription:
    late StreamSubscription subscription;
    
  2. In the initState method of the _StreamHomePageState class, remove StreamTransformer and set the subscription. The final result...

Allowing multiple stream subscriptions

By default, each stream allows only a single subscription. If you try to listen to the same subscription more than once, you get an error. Flutter also has a specific kind of stream, called a broadcast stream, which allows multiple listeners. In this recipe, you will see a simple example of using a broadcast stream.

Getting ready

In order to follow along with this recipe, you should have completed the code in the previous recipe, Subscribing to stream events.

How to do it...

For this recipe, we’ll add a second listener to the stream that we built in the previous recipes in this chapter:

  1. At the top of the _StreamHomePageState class, in the main.dart file, declare a second StreamSubscription, called subscription2, and a string, called values:
    late StreamSubscription subscription2;
    String values = '';
    
  2. In the initState method, edit the first subscription and listen to the stream with...

Using StreamBuilder to create reactive user interfaces

Streambuilder is a widget that listens to events emitted by a stream, and whenever an event is emitted, it rebuilds its descendants. Like the FutureBuilder widget, which we saw in Chapter 7, The Future Is Now: Introduction to Asynchronous Programming, StreamBuilder makes it extremely easy to build reactive user interfaces that update every time new data is available.

In this recipe, we will update the text on the screen with StreamBuilder. This is very efficient compared to the update that happens with a setState method and its build call, as only the widgets contained in StreamBuilder are actually redrawn.

Getting ready

In order to follow along with this recipe, you will build an app from scratch. Call this new app streambuilder_app.

How to do it...

For this recipe, we will create a stream and use StreamBuilder to update the user interface. Perform the following steps:

  1. In your new app, in the lib...

Using the BLoC pattern

When using the BLoC pattern, everything is a stream of events. A BLoC (which stands for Business Logic Component) is a layer between any source of data and the user interface that will consume the data.

Examples of sources include HTTP data retrieved from a web service, or JSON received from a database.

The BLoC receives streams of data from the source, processes it as required by your business logic, and returns streams of data to its subscribers.

A simple diagram of the role of a BLoC is shown in Figure 11.10:

Diagram  Description automatically generated

Figure 10.10: The BLoC pattern

The main reason for using BLoCs is to separate the concern of the business logic of your app from the presentation that occurs with your widgets, and it is especially useful when your apps become more complex and need to share state in several different places. This makes it easier to reuse your code in different parts of your application, or even in different apps. Also, as BLoCs are completely...

Summary

In this chapter, you saw how to use a Stream in a Flutter app, read and write data to streams, build reactive user interfaces based on Streams, and implement the BLoC state management pattern.

You used StreamControllers and their Streams and Sinks. You learned how to subscribe to stream events, allow multiple stream subscriptions, and use the StreamBuilder widget to create reactive user interfaces.

You saw how to handle data and errors generated by streams, ensuring your app can manage different outcomes gracefully.

Now you can use Streams and BLoCs in your Flutter applications; this can help you create more robust, maintainable, and scalable apps that respond seamlessly to changing data and user interactions.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Flutter Cookbook, Second Edition - Second Edition
Published in: May 2023Publisher: PacktISBN-13: 9781803245430
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Simone Alessandria

Simone Alessandria wrote his first program when he was 12. It was a text-based fantasy game for the Commodore 64. Now, he is a trainer (MCT), author, speaker, passionate software architect, and always a proud coder. He is the founder and owner of Softwarehouseit. His mission is to help developers achieve more through training and mentoring. He has authored several books on Flutter, including Flutter Projects, published by Packt, and web courses on Pluralsight and Udemy.
Read more about Simone Alessandria