Streams in, streams out…
How to listen to real-time data apart from StreamBuilder….? Hmmm…..
Begin…
Recently, a state management package called Provider was announced by Flutter team at Google I/O 2019.
How to use…
Add this dependency in your pubspec.yaml.
provider: ^2.0.0+1

Listen to data…
We had StreamBuilder in Flutter…
Hands down, best widget for listening real-time data…
This takes two arguments
- A stream
- A builder, that can convert the elements of the stream to widgets
StreamBuilder(
stream: //YOUR STREAM,
builder: (BuildContext context, AsyncSnapshot snapshot){
return //YOUR CHILD;
})
Now we also have StreamProvider……..:)
This comes from provider package.
StreamProvider<LocationModelNormal>.value(
initialData: LocationModelNormal.initialData(),
stream: locationStreamInstance.specificLocation(_secondWonder),
child: SecondStreamWidget(),
),
- In StreamProvider, we need to specify the type of object we are listening to….
In above case, LocationModelNormal (model class)…
LocationModelNormal class (below)….
class LocationModelNormal {
final String name;
final String url;
final GeoPoint coordinates;
final String videoURL;
LocationModelNormal({
this.name,
this.url,
this.coordinates,
this.videoURL,
});
factory LocationModelNormal.fromMap(Map<String, dynamic> data) {
return LocationModelNormal(
name: data['name'] ?? '',
url: data['url'] ?? '',
coordinates: data['location'] ?? null,
videoURL: data['link'] ?? '',
);
}
factory LocationModelNormal.initialData() {
return LocationModelNormal(
coordinates: null,
name: '',
videoURL: '',
url:'',
);
}
}
2. Next, we provide the initialData.
In our case, LocationModelNormal.initialData()….(See the snippet above)
3. Finally, we provide the child widget.
In our case, SecondStreamWidget()…
Pretty similar to StreamBuilder, right !!!!!!!!! 🙂
Access Data in Child…
Now that we have StreamProvider setup, we need to show the results in the child…
For accessing the data, (in your child)….
var data = Provider.of<LocationModelNormal>(context);
Here, we specified the result expected from our stream, using Provider.of<Type>(context)..
In our case, Type = LocationModelNormal
In action,
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(‘${data.name}'),
),
where, data = the variable we specified above…
Listen to Network Changes…

When injecting many values in big applications, Provider
can rapidly become pretty nested, thats why we have MultiProvider
MultiProvider(
providers: [
Provider<Foo>.value(value: foo),
Provider<Bar>.value(value: bar),
Provider<Baz>.value(value: baz),
],
child: someWidget,
)
Use-Case…
In our example, we listen to the network changes, before fetching other streams…..
How to do,
- Install the connectivity dependency
- Wrap your MaterialApp with MultiProvider…
return MultiProvider(
providers: [
StreamProvider<ConnectionStatus>.value(
stream:streamConnectivityService().connectivityController.stream,
),
],
child: MaterialApp(
home: Home(),
),
);
Here, the model class is ConnectionStatus…
Now, your Home widget will get the changes in the network connectivity…You can render different UIs accordingly…
Values emitted are….
Wifi, offline or mobile data….
Widget build(BuildContext context) {
var network = Provider.of<ConnectionStatus>(context);
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
if (network == ConnectionStatus.wifi ||
network == ConnectionStatus.mobileData) {
return Container(
child: child,
);
}
return Container(
height: _height,
width: _width,
child: Text('YOU ARE OFFLINE'),
);
}
Src code : https://github.com/AseemWangoo/flutter_programs/blob/master/provider.zip