In this example, we are going to show you how to enable Caching of JSON or any other resource from REST API. Cached JSON will be fetched whenever your app is offline or disconnected. We have used "Pull to refresh" to refresh the cache. See the example below:
First of all, you need to add dio and dio_http_cache flutter Packages in your project by adding the following lines in pubspec.yaml file.
dependencies:
flutter:
sdk: flutter
dio: ^4.0.4
dio_http_cache: ^0.3.0
Here, dio package is for fetching JSON or any other resource from REST API, and dio_http_cache package is to be used for caching resources fetched from REST API.
Read This Also: How to Fetch Data from REST API in Flutter
Import dio and dio_http_cache in your dart script:
import 'package:dio/dio.dart';
import 'package:dio_http_cache/dio_http_cache.dart';
Add this line before API Request, you can do this both on GET and POST Method:
dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: "http://www.google.com")).interceptor);
Enable Caching on REST API request:
Dio().get(
"http://www.google.com",
options: buildCacheOptions(Duration(days: 7)),
);
Read this also: How to Enable Cache and Lazy Loading Image in Flutter App
Set maxState if you want to return cache in case of 500, 400 error:
buildCacheOptions(Duration(days: 7), maxStale: Duration(days: 10))
You can force refresh too:
buildCacheOptions(Duration(days: 7), forceRefresh: true)
PHP Code at the server-side script that generates JSON:
<?php
$return["error"] = false;
$return["msg"] = "";
$return["data"] = array();
if(isset($_REQUEST["auth"])){
$authkey = $_REQUEST["auth"];
if($authkey == "kjgdkhdfldfguttedfgr"){
$countries = array(
array(
"name"=>"Canada",
"capital"=>"Ottawa"
),
array(
"name"=>"Brazil",
"capital"=>"Brasília"
),
array(
"name"=>"Finland",
"capital"=>"Helsinki"
),
array(
"name"=>"Nepal",
"capital"=>"Kathmandu"
)
);
$return["data"] = $countries;
}else{
$return["error"] = true;
$return["msg"] = "Authentication error.";
}
}else{
$return["error"] = true;
$return["msg"] = "Send auth key.";
}
header('Content-Type: application/json');
echo json_encode($return);
//converting array to JSON string
JSON Output:
{
"error":false,
"msg":"",
"data":[
{
"name":"Canada",
"capital":"Ottawa"
},
{
"name":"Brazil",
"capital":"Brasília"
},
{
"name":"Finland",
"capital":"Helsinki"
},
{
"name":"Nepal",
"capital":"Kathmandu"
}
]
}
Flutter Code: In this code, "Pull to refresh" is also enabled using RefreshIndicator() widget
import 'package:dio/dio.dart';
import 'package:dio_http_cache/dio_http_cache.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Home()
);
}
}
class Home extends StatefulWidget {
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
late Response response;
Dio dio = Dio();
bool error = false; //for error status
bool loading = false; //for data featching status
String errmsg = ""; //to assing any error message from API/runtime
var apidata; //for decoded JSON data
bool refresh = false; //for forcing refreshing cache
@override
void initState() {
dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: "http://192.168.0.235")).interceptor);
getData(); //fetching data
super.initState();
}
getData() async {
setState(() {
loading = true; //make loading true to show progressindicator
});
String url = "http://192.168.0.235/test/data.php?auth=kjgdkhdfldfguttedfgr";
//don't use "http://localhost/" use local IP or actual live URL
Response response = await dio.get(url, options: buildCacheOptions(
Duration(days: 7), //duration of cache
forceRefresh: refresh, //to force refresh
maxStale: Duration(days: 10), //before this time, if error like
//500, 500 happens, it will return cache
));
apidata = response.data; //get JSON decoded data from response
print(apidata); //printing the JSON recieved
if(response.statusCode == 200){
//fetch successful
if(apidata["error"]){ //Check if there is error given on JSON
error = true;
errmsg = apidata["msg"]; //error message from JSON
}
}else{
error = true;
errmsg = "Error while fetching data.";
}
loading = false;
refresh = false;
setState(() {}); //refresh UI
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Cache JSON from REST API"),
backgroundColor: Colors.redAccent,
),
body: RefreshIndicator(
onRefresh: () async {
refresh = true;
getData();
},
child:SingleChildScrollView(
child:Container(
constraints: BoxConstraints(
minHeight: 1500
),
alignment: Alignment.topCenter,
padding: EdgeInsets.all(20),
child: loading?
CircularProgressIndicator(): //if loading == true, show progress indicator
Container( //if there is any error, show error message
child:error?Text("Error: $errmsg"):
Column( //if everything fine, show the JSON as widget
children:apidata["data"].map<Widget>((country){
return Card(
child: ListTile(
title: Text(country["name"]),
subtitle: Text(country["capital"]),
),
);
}).toList(),
)
)
)
)
)
);
}
}
In this code, we have cached JSON for 7 days which is fetched from REST API. In the scroll view, we have enabled the Pull to refresh indicator so that whenever the User tries to refresh to data, we have forced refresh the cache.
You can run the above code. It will get the data from REST API, and cache it. Turn off your wifi or internet connection, and again restart the app. It will show the list from cache JSON.
In this way, you can cache JSON or any other resource from REST API in Flutter App.
Please Wait...
No any Comments on this Article