MobX Flutter With REST API Calls
In this article, we are going to integrate mobx library in our flutter applications to fetch data from api with state management. We already get api data with different ways. You can check out at HERE.
MobX is used to manage state of our flutter applications. MobX library connect data of our application with our app UI. There are three main components in MobX library: Observable, Actions and Reactions.
Observables are used to observe any changes in application. They represent reactive state of application. Observables can be object or anything. They can be scalars to complex object structure.
Actions are the methods using which we can mutate the observables. If we use actions then we did not need to mutate observables directly.
Reactions are observers which are used to observe observables. They notified the application when observables are changed. Reactions complete the MobX cycle of observables, actions and reactions.
Add required libraries for MobX Flutter in pubspec.yaml file
mobx library provides state management related widgets. flutter_mobx library provides observer widgets that automatically rebuild the application when observables change. http library is used to fetch api data. build_runner library is used to generate some classes. mobx_codegen library provides annotations.
mobx: ^1.2.1+4
flutter_mobx: ^1.1.0+2
http: ^0.12.0+4
dev_dependencies:
build_runner: ^1.11.5
mobx_codegen: ^1.1.2
Create Model Classes to parse api data
First we need to create data model classes to handle api data.
int userId;
String userName, userEmail, userPhone, userWebsite;
UserAddress userAddress;
UserCompany userCompany;
User(
{this.userId,
this.userName,
this.userEmail,
this.userPhone,
this.userWebsite,
this.userAddress,
this.userCompany});
factory User.fromJSON(Map<String, dynamic> parsedJson) {
return User(
userId: parsedJson[‘id’],
userName: parsedJson[‘name’],
userEmail: parsedJson[’email’],
userPhone: parsedJson[‘phone’],
userWebsite: parsedJson[‘website’],
userAddress: UserAddress.fromJSON(parsedJson[‘address’]),
userCompany: UserCompany.fromJSON(parsedJson[‘company’]),
);
}
}
class UserAddress {
String userStreet, userSuite, userCity, userZipCode;
UserAddress({this.userStreet, this.userSuite, this.userCity, this.userZipCode});
factory UserAddress.fromJSON(Map<String, dynamic> parsedJson) {
return UserAddress(
userStreet: parsedJson[‘street’],
userSuite: parsedJson[‘suite’],
userCity: parsedJson[‘city’],
userZipCode: parsedJson[‘zipcode’],
);
}
}
class UserCompany {
String name, catchPhrase, bs;
UserCompany({this.name, this.catchPhrase, this.bs});
factory UserCompany.fromJSON(Map<String, dynamic> parsedJson) {
return UserCompany(
name: parsedJson[‘name’],
catchPhrase: parsedJson[‘catchPhrase’],
bs: parsedJson[‘bs’]);
}
}
Create Api Service to fetch API data
Now we make http request to fetch user data from api.
import ‘package:http/http.dart’ as http;
import ‘user.dart’;
class ApiService {
List<User> listUsers;
Future getApiData(String url) async {
final apiResponse = await http.get(url);
if (apiResponse.statusCode == 200) {
final data = jsonDecode(apiResponse.body);
listUsers = (data as List).map((json) {
return User.fromJSON(json);
}).toList();
return listUsers;
} else {
print(“Error!”);
}
}
}
Create Store Class for MobX Flutter
For MobX library, we need to create a class which contain business logic of our flutter applications. So we can control all data related operations of our application using this central class.
import ‘package:mobx/mobx.dart’;
import ‘api_service.dart’;
part ‘user_store.g.dart’;
class UserStore = _UserStore with _$UserStore;
abstract class _UserStore with Store {
final ApiService apiService = ApiService();
@observable
ObservableFuture<List<User>> listUsersFuture;
@action
Future fetchUsersData() => listUsersFuture = ObservableFuture(apiService
.getApiData(‘https://jsonplaceholder.typicode.com/users’)
.then((users) => users));
void getUsersData() {
fetchUsersData();
}
}
Display API Data
import ‘package:flutter/material.dart’;
import ‘user.dart’;
import ‘user_store.dart’;
class HomeScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return HomeScreenState();
}
}
class HomeScreenState extends State<HomeScreen> {
UserStore store = UserStore();
@override
void initState() {
super.initState();
store.getUsersData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<User>>(
future: store.listUsersFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.separated(
itemBuilder: (context, index) {
var user = (snapshot.data as List<User>)[index];
return Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
user.userName,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 22),
),
SizedBox(height: 5),
Text(user.userEmail),
SizedBox(height: 5),
Text(user.userAddress.userStreet +
” ” +
user.userAddress.userSuite +
” ” +
user.userAddress.userCity +
” ” +
user.userAddress.userZipCode),
SizedBox(height: 5),
Text(user.userPhone),
SizedBox(height: 5),
Text(user.userWebsite),
SizedBox(height: 5),
Text(user.userCompany.name),
SizedBox(height: 5),
Text(user.userCompany.catchPhrase),
],
),
);
},
separatorBuilder: (context, index) {
return Divider();
},
itemCount: (snapshot.data as List<User>).length);
} else if (snapshot.hasError) {
return Center(
child: Text(“${snapshot.error}”),
);
}
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.cyanAccent,
),
);
},
));
}
}


Pingback: Flutter Fonts Integration - CodingWithDhrumil