Previously we have seen how to use Provider to manage state of your app. We have simulated a todo app for state management using Provider.
Here we will see how to use Provider to load the data from the network or server using restful api request.
We will six simple steps to finish this data loading and loading animation. Go ahead install the below three packages
Take a look at the simple steps
1. Understand your data
We will create a get request. So we will use the below link for fetching data from server.
https://jsonplaceholder.typicode.com/posts/2
You can view the data in postman
Here we will use two fields title and body for data model.
2. Create data model.
Based on the above information we will create a new class name data_model.dart
class DataModel {
final String title;
final String body;
DataModel({required this.title, required this.body});
factory DataModel.fromJson(Map<String, dynamic> json) {
return DataModel(
title: json['title'] ?? "",
body: json['body'] ?? "",
);
}
}
Here we have fromJson method for converting server json response to DataModel object.
We have just used two fields title and body
3. Create a service class for data loading
Now we create a service_class.dart for laoding data from the server using restful api. Here we will also use Http package.
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'data_class.dart';
import 'data_model.dart';
Future<DataModel?> getSinglePostData() async {
DataModel? result;
try {
final response = await http.get(
Uri.parse("https://jsonplaceholder.typicode.com/posts/2"),
headers: {
HttpHeaders.contentTypeHeader: "application/json",
},);
if (response.statusCode == 200) {
final item = json.decode(response.body);
result = DataModel.fromJson(item);
} else {
print("error");
}
} catch (e) {
log(e.toString());
}
return result;
}
In the above code, we used http.get to pass the url and headers and make the http get request. If we get the data from the server, we will get status code 200. Then we decode the data using json.decode method and make an object by calling DataModel.fromJson() method.
4. Create a data class using ChangeNotifier
Create class name data_class.dart and put the code
import 'data_model.dart';
class DataClass extends ChangeNotifier {
DataModel? post;
bool loading = false;
getPostData() async {
loading = true;
post = (await getSinglePostData())!;
loading = false;
notifyListeners();
}
}
Our data class extends ChangeNotifier. It loads the from service class and notifies ui about new up coming data. We also use notifyListeners() to get the updated data in the UI.
5. Create Provider with ChangeNotifierProvider
In our main.dart we create provider like below
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:provider/provider.dart';
import 'data_class.dart';
import 'data_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(create: (context)=>DataClass(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home:ProviderDemoScreen()
),);
}
}
and in main.dart we created a class name ProviderDemoScreen() for UI and show data from the provider class, that comes from restful api
class ProviderDemoScreen extends StatefulWidget {
const ProviderDemoScreen({Key? key}) : super(key: key);
@override
_ProviderDemoScreenState createState() => _ProviderDemoScreenState();
}
class _ProviderDemoScreenState extends State<ProviderDemoScreen> {
@override
void initState() {
super.initState();
final postModel = Provider.of<DataClass>(context, listen: false);
postModel.getPostData();
}
@override
Widget build(BuildContext context) {
final postModel = Provider.of<DataClass>(context);
return Scaffold(
appBar: AppBar(
title: Text("Provider Demo"),
),
body: Container(
padding: EdgeInsets.all(20),
child: postModel.loading?Center(
child: Container(
child: SpinKitThreeBounce(
itemBuilder: (BuildContext context, int index) {
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: index.isEven ? Colors.red : Colors.green,
),
);
},
),
),
):Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(top: 40, bottom: 20),
child: Text(
postModel.post?.title ?? "",
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
),
),
Container(
child: Text(postModel.post?.body ?? ""),
)
],
),
),
),
);
}
}