Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - How does MultiProvider work with providers of the same type?

For example, I am trying to obtain data emitted for multiple streams at once, but 2 or more of these streams emit data of the same type, lets say a string.

My question is, is it possible to use MultiProvider and use multiple StreamProvider (or any provider, but I am interested in this case) of the same type while still being able to access the data emitted by each one of them?

A solution for this is using a StreamBuilder when using common data types but I really like what the MultiProvider offers in terms of cleaner code.

Example:

class MyScreen extends StatelessWidget {
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        StreamProvider<String>(stream: Observable.just("stream1")),
        StreamProvider<String>(stream: Observable.just("stream2")),
        StreamProvider<String>(stream: Observable.just("stream3"))
      ],
      child: Builder(
        builder: (BuildContext context) {
          AsyncSnapshot<String> snapshot =
              Provider.of<AsyncSnapshot<String>>(context);
          String data = snapshot.data;
          return Text(data); 
        },
      ),
    );
  }
}
like image 388
Ali Amin Avatar asked Jun 08 '19 10:06

Ali Amin


People also ask

How does MultiProvider work Flutter?

MultiProvider class Null safetyA provider that merges multiple providers into a single linear widget tree. It is used to improve readability and reduce boilerplate code of having to nest multiple layers of providers. The widget tree representation of the two approaches are identical.


1 Answers

MultiProvider or not doesn't change anything. If two providers share the same type, the deepest one overrides the value.

It's not possible to obtain the value from a provider that is not the closest ancestor for a given type.

If you need to access all of these values independently, each should have a unique type.

For example, instead of:

Provider<int>(
  value: 42,
  child: Provider<int>(
    value: 84,
    child: <something>
  ),
)

You can do:

class Root {
  Root(this.value);

  final int value;
}

class Leaf {
  Leaf(this.value);

  final int value;
}


Provider<Root>(
  value: Root(42),
  child: Provider<Leaf>(
    value: Leaf(84),
    child: <something>
  ),
)

This allows to obtain each value independently using:

Provider.of<Root>(context)
Provider.of<Leaf>(context);
like image 178
Rémi Rousselet Avatar answered Sep 23 '22 02:09

Rémi Rousselet