Harvinder Singh
CodeBlogs

Follow

CodeBlogs

Follow
Bloc State Management Flutter (Made Easy)

Bloc State Management Flutter (Made Easy)

Harvinder Singh's photo
Harvinder Singh
·Aug 28, 2022·

4 min read

In this series you will learn everything about flutter bloc state management, including the basics of streams and advanced tools such as flutter_bloc/bloc package.

What Is State management ?

State is the current data or information that the user can view or manipulate.

For example, text fields, OK buttons, radio buttons, etc. There are several types of data that need to be maintained, such as whether a button has been pressed or not, or whether a toggle button is on or off. A state is the data that a user generally sees, interacts with, or generates after some event. State management is the process of maintaining all of these information(state).

The problem :

As an application grows, state management becomes very messy; simple tools like setState in Flutter can't handle large changes at once, and inherited widgets can create a lot of boilerplate code.

The Solution :

In order to overcome the above problem, we can use tools like flutter_bloc/bloc these packages are created by the community, are very useful for reducing boilerplate code, and are easy to use.

Before going deep into the flutter_bloc package we need to make our basics clear these basics includes :

:: streams

:: cubit%

:: bloc

Streams :

Streams are sequences of asynchronous data. We can provide and retrieve data from streams by using them as water hoses with a sink and drain. We need to understand Dart's core features and basic application of streams before we can fully grasp the concept of bloc.

As we know the basic definition of streams lets generate our own stream using the yield keyword.

1_tgS8HFG7KWzL8SvzqRsQbQ.jpeg

Here, we have a function getRandomNumberStream, which can be found in "lib/streamGenerators.dart" (clone the repo and take a look at the structure) whose output streams we have specified by using async*. In addition, we have a Future.delayed() method that delays our execution for 1000 ms on the first run, and then for 500 ms on every subsequent run. Our output is then yielded (yielded).

It basically outputs data in the form of a stream, so this function will be our go-to for all our stream needs.

Now let me brief about all the basic functions that are available with streams.

.map: .map helps us to map the event that we are getting from the stream by passing them to a function. ex

StreamGenerators.getRandomNumberStream(10).map((event) => "This event --$event-- is mapped");
op:
This event --$0-- is mapped
This event --$1-- is mapped
This event --$2-- is mapped
This event --$3-- is mapped
This event --$4-- is mapped

.take: .take will only take the first N values and drain the rest of the values. ex

StreamGenerators.getRandomNumberStream(10).take(5)
        .map((event) => event.toString() + " .take(5)");
op: 
0 .take(5)
1 .take(5)
2 .take(5)
3 .take(5)
4 .take(5)

.where: .where this can be helpful in case we want to filter our stream on the basis of some condition. ex:

StreamGenerators.getRandomNumberStream(20)
        .where((event) =>
            event % 2 !=
            0) 
        .map((event) =>
            "$event : filtering stream by eleminating element which are  divisible of 2 ")
op:
1:filtering stream by eleminating element which are  divisible of 2
3:filtering stream by eleminating element which are  divisible of 2
5:filtering stream by eleminating element which are  divisible of 2
7:filtering stream by eleminating element which are  divisible of 2
9:filtering stream by eleminating element which are  divisible of 2
11:filtering stream by eleminating element which are  divisible of 2
13:filtering stream by eleminating element which are  divisible of 2
15:filtering stream by eleminating element which are  divisible of 2
17:filtering stream by eleminating element which are  divisible of 2
19:filtering stream by eleminating element which are  divisible of 2

That’s enough for basics lets tale a look at stream subscription, Stream sink, and stream function.

Stream Subscription: In other words, stream subscription is like a handle to a stream, which can be used to control the stream's behavior. It is important to know when to stop, when to resume, and when to cancel a project. You can check out the StreamSubscription example in the git repo. Let's take a brief look at stream subscription.

StreamSubscription streamSubscription =
        StreamGenerators.getRandomNumberStream(20).listen((event) { }
//accessing methods of stream
streamSubscription.pause();
streamSubscription.resume();
treamSubscription.cancel();

In the above code, we are first subscribing to a stream using the listen method. Then we are accessing the methods of stream subscription. These methods are pretty self-explanatory.

sink: are the opening of the stream where we can input data that we want our stream to consume. Let's take a look at an example.

final _counterStateController = StreamController<int>();
StreamSink<int> get _inCounter => _counterStateController.sink;
Stream<int> get counter => _counterStateController.stream;

In the above example, we have created a StreamController and accessing its sink and stream functionality using the StreamController object.

 
Share this