Using selector in provider


View the demo here


We will cover briefly about

  1. Selector 
  2. Using Selector with Provider

Current Status

Let’s start by describing what we have currently. In our demo, we have an input form with 3 fields:

  • Name Field
  • Age Field
  • Email Field
Using Selector in Provider
Using Selector in Provider

There are 3 text fields, which basically show us the values inside each of the input fields.

Approach 1 (All this time I took)

Using Selector in Provider
Using Selector in Provider

As per this approach, we would have a 

  • ChangeNotifierProvider, at the top of the widget tree.
  • Followed by a consumer, before we start our form
  • Finally, our Form UI

Things to consider:

Your Form fields will undergo unnecessary builds. Let me explain.

For instance, say you are entering the age field, other fields (name and email field), will continue rebuilding since the Consumer widget is above the Form.

This is true for any other field also.

As per the Consumer documentation:

builder may be called multiple times (such as when the provided value change).

In our case, we just have 3 fields inside FormUI, so we can go with approach1, but what if we had a complex UI, think about it!

Approach 2 (Using Selector in Provider)

Using Selector in Provider
Using Selector in Provider

When I started to use Provider in Flutter, most of the times, it was either

Now we will use a Selector.

In this approach, we have ChangeNotifierProvider at the top, followed by our UI.

So, for adding values to our model (ChangeNotifier model, UserData) we use<UserData>()

Using Selector in Provider
Using Selector in Provider

This is an extension included in Provider, now we have the input inside our model(UserData).


Note: Setting of the value, notifies the model since the setter implements notifyListeners.

set emailAddress(String emailAddress) {
_emailAddress = emailAddress;

Similarly, we do this for all the input fields (name, age, and email)

Let’s say, we want to display the values entered in these fields in real-time.

Selector in Provider
Selector in Provider
  • Email Text should only listen to Email Field.
  • Name + Age Text should only listen to changes in Name and Age Fields
  • For displaying all values of the form, we need to listen to every field

Email Text

final _email =<UserData, String>((model) => model.emailAddress);
return Text('(Listen to Email) Email : $_email');

We use

As per documentation

Watch a value of type [T] exposed from a provider, and listen only partially to changes. 

By using [select], instead of watching the entire object, the listener will rebuild only if the value returned by selector changes.

Hence for email text, we select only the email field and get notified when it changes. 

Name + Age Text

Here, we want to listen to two fields from our notifier model. 

Time to introduce a new package tuple.

This package gives us options to select the number of values and comes recommended by Provider. Currently supports 7 values.

To select multiple values without having to write a class that implements ==, the easiest solution is to use a “Tuple” from tuple

Since we need 2 fields, we use Tuple2

Tuple2 example
Tuple2 example

Here, we use the Selector widget

An equivalent to [Consumer] that can filter updates by selecting a limited amount of values and prevent rebuild if they don’t change.

Criteria: Tuple2 of Name field and age field, Tuple2<String, int>.

Hence, inside our builder, we can retrieve these values by 

data.item1 // For name, since First value of Tuple is String

data.item2 // For age, since Second value of Tuple is int

All Text

Here, we need to listen to all the values inside our notifier model. This turns out to be a good use-case for Consumer.

  builder: (_, data, __) {
    return Text(
          '(Listening to all) Name : ${} >>> Age : ${data.age} >>> Email${data.emailAddress}',

Hosted URL :

Source code for Flutter Web App..

Valuable comments