Flutter StateManagement with Provider

Karthik Ponnam
Flutter Community
Published in
4 min readMay 19, 2019

Hello friends,

Here we have big news from flutter team in IO19

Flutter now announced their support for web. for more details you can https://flutter.dev/web

Alongside the flutter web, they also announced a new plugin for StateManagement Here how to use it in your application

So Let’s get started

Before looking into providers lets see whatsis ChangeNotifier this plugin uses ChangeNotifier to to listen and update any changes.

What is ChangeNotifier

Form docs

A class that can be extended or mixed in that provides a change notification API using [VoidCallback] for notifications.

[ChangeNotifier] is optimized for small numbers (one or two) of listeners. It is O(N) for adding and removing listeners and O(N²) for dispatching notifications (where N is the number of listeners)

Provider

Existing providers

provider exposes a few different kinds of "provider" for different types of objects.

https://pub.dev/packages/provider

Let's get started with our code

first things first let add plugin to pubspec.yaml

provider: ^2.0.1
http: ^0.12.0+2

Let's Write our provider class first we name it AppState

Our AppState is extended with ChangeNotifier which is used to notify its listeners when we call notifyListeners()

In the code, we declared two methods setDisplayText and getDisplayText which are used to read and write the value in our state

Now we move to our main.dart

In the code, we can notice we have used ChangeNotifierProvider which is provided from out provider plugin

It accepts two parameters one is builder and the other is child

return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ChangeNotifierProvider<AppState>(
builder: (_) => AppState(),
child: MyHomePage(),
));
}

Inside the MyHomePage we have a Scaffold with Column which has two Widgets TextDisplay() and TextEditWidget()

TextDisplay(),
TextEditWidget(),

Here is our TextDisplay() in text_display.dart

In the above code we see

Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);

return Container(
padding: const EdgeInsets.all(16.0),
child: Text(
appState.getDisplayText,
style: TextStyle(
fontSize: 24.0,
),
),
);
}
final appState = Provider.of<AppState>(context);

This above line of code will get the provider that listens to any changes optionally we can also get a provider without a listener by providing listen: false

final appState = Provider.of<AppState>(context, listen: false);

Now in order to access text, we have a function in our provider called getDisplayText

appState.getDisplayText()

Here is out TextEditWidget() in text_edit.dart

In the above code, we get our appState inside the build function

final appState = Provider.of<AppState>(context);

In order to manipulate the text in the state we call setDisplayText(text) function

TextField(
controller: _textEditingController,
decoration: InputDecoration(
labelText: "Some Text",
border: OutlineInputBorder(),
),
onChanged: (changed) => appState.setDisplayText(changed),
onSubmitted: (submitted) => appState.setDisplayText(submitted),
)

we are updating the state whenever out text is changes

onChanged: (changed) => appState.setDisplayText(changed)

Now we perform network operation

Now inside our app state, we have some additional functions and variables

String _dataUrl = "https://reqres.in/api/users?per_page=20";
String _jsonResonse = "";
bool _isFetching = false;

bool get isFetching => _isFetching;

Future<void> fetchData() async {
_isFetching = true;
notifyListeners();

var response = await http.get(_dataUrl);
if (response.statusCode == 200) {
_jsonResonse = response.body;
}

_isFetching = false;
notifyListeners();
}

String get getResponseText => _jsonResonse;

List<dynamic> getResponseJson() {
if (_jsonResonse.isNotEmpty) {
Map<String, dynamic> json = jsonDecode(_jsonResonse);
return json['data'];
}
return null;
}

Here we have a few more functions fetchData, getResponseText and getResponseJson

fetchData will perform the network operation and update the variable with the response data (you can parse your JSON to custom model here and save it in a List)

getResponseText will return the plain text response

getResponseJson will convert the response text to a Map and returndata field inside it which is a list of Map

To see the final app_state.dart visit below link

Now inside out MyHomePage widget we add two more widgets to our column

RaisedButton(
onPressed: () => appState.fetchData(),
child: Text("Fetch Data from Network"),
),
ResponseDisplay(),

So I am calling appState.fetchData() whenever I press the button now fetchData will take care of all the updating of the state

Here is our ResponseDisplay Widget named response_display.dart

Here in the above code we parse the JSON and build a list of data

--

--

Karthik Ponnam
Flutter Community

❤️ to Code. Full Stack Developer, Flutter, Android Developer, Web Development, Known Languages Java, Python so on.,