How to Fetch Data from REST API in Flutter

In this example, we are going to show you how to fetch JSON data or any other resource from REST API generated by PHP, Node.js, Python, or any server-side scripting language. We will use Dio() package for API calls. See the example below:

First, you need to add Dio Flutter package in your project by adding the following lines in pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  dio: ^4.0.4

Import package to script:

import 'package:dio/dio.dart';

Add Internet Permission by adding this line in android/app/src/main/AndroidManifest.xml before <application>

<uses-permission android:name="android.permission.INTERNET"/>

Response response;
var dio = Dio();

response = await dio.get('/products.php?id=12&name=shoe');
print(response.data.toString());

// Optionally the request above could also be done as
response = await dio.get('/products.php', queryParameters: {'id': 12, 'name': 'shoe'});
print(response.data.toString());

You can add Caching on API Request: How to Cache JSON from REST API in Flutter

Response response;
var dio = Dio();

response = await dio.post('products.php', data: {'id': 12, 'name': 'tshirt'});

You may get an "Insecure HTTP is not allowed by platform" error, see the solution here: How to Solve ’Insecure HTTP is not allowed by platform’ Error

PHP Code: located at test/data.php

<?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 from PHP script:

{
   "error":false,
   "msg":"",
   "data":[
      {
         "name":"Canada",
         "capital":"Ottawa"
      },
      {
         "name":"Brazil",
         "capital":"Brasília"
      },
      {
         "name":"Finland",
         "capital":"Helsinki"
      },
      {
         "name":"Nepal",
         "capital":"Kathmandu"
      }
   ]
}

Flutter/Dart Code: From REST API JSON to Widget View

import 'package:dio/dio.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
  
  @override
  void initState() {
    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); 
      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;
      setState(() {}); //refresh UI 
  }

  
  @override
  Widget build(BuildContext context) {
    
    return Scaffold(
         appBar: AppBar(
            title: Text("Fetch Data from REST API"),
            backgroundColor: Colors.redAccent,
         ),

         body: Container(
           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 way, you can fetch JSON data from the web URL, and show the list of data as ListView in the Flutter app.

No any Comments on this Article


Please Wait...