Fetching data from internet is one of the most common operations that every developers should master. In Flutter, this operation is pretty straightforward. In this post we will learn how to handle data from fetching to displaying it on our mobile apps. Setup First thing first, we need to know where we are going to fetch the data from. We will use . You can always choose another source of data, but for the purpose of this post this API key is more than enough. Also, we don't need to register anything to make an API calls to this dummy API. Dummy Rest API Example Second, we need to install the required plugins for this app through . pubspec.yaml dependencies: json_annotation: ^2.4.0 http: 0.12 .0 +4 dev_dependencies: build_runner: ^1.0.0 json_serializable: ^3.0.0 Then run flutter pub get Now we are good to go. Model Just like other OOP languages, we need to create model class for our incoming data. Let's start by creating . models.dart Since most data are JSON typed when you fetch it from the internet, we will need to handle it because JSON data are not automatically parsed. To do so we will use json_serializable plugin, which will do the dirty jobs for us. ; ; () { id; (name: ) employeeName; (name: ) employeeSalary; (name: ) employeeAge; (name: ) profileImage; Employees({ .id, .employeeName, .employeeSalary, .employeeAge, .profileImage}); Employees.fromJson( < , > json) => _$EmployeesFromJson(json); < , > toJson() => _$EmployeesToJson( ); } import 'package:json_annotation/json_annotation.dart' part 'model.g.dart' @JsonSerializable class Employees final String @JsonKey 'employee_name' final String @JsonKey 'employee_salary' final String @JsonKey 'employee_age' final String @JsonKey 'profile_image' final String this this this this this factory Map String dynamic Map String dynamic this There will be errors because we refer to a non-existent variable and file. In order to wipe those errors, run build runner to generate additional dart file for our model: pub run build_runner build HTTP Request In this part, we will separate the UI and logic of the apps. Let's start by creating network_helper.dart Handling requests in Flutter is easy. Take a look at the code below: http; ; ; url = ; { getPath() { url + ; } Future< <Employees>> getEmployees() { res = http. (getPath()); (res.statusCode == ) { json = jsonDecode(res.body); data = json[ ]; data.map((employees) => Employees.fromJson(employees)).toList(); } { Exception( ); } } } import 'package:http/http.dart' as import 'dart:convert' import '../models/model.dart' const "http://dummy.restapiexample.com/" class GetEmployee String return "api/v1/employees" List async final await get if 200 var List 'data' return new else throw 'Failed to fetch data' First we import . We use this package in order to use method. This method will be responsible for parsing our json to be readable by dart. dart:convert jsonDecode() Notice that we use in the beginning of our declaration. This will tell Flutter that we want to return a object when we call . Future Future getEmployees() A is used to represent a value that will be available in some time in the future. For a more advanced explanation, read . Future here Display Our Data With ListView.builder After we receive the data we fetched from the internet, we need to update our widget so that it can display the data in our app. ; ; ; { id = ; title = ; _HomeScreenState createState() => _HomeScreenState(); } { Widget build(BuildContext context) { Scaffold( appBar: AppBar( title: Text(HomeScreen.title), ), body: Center( child: _employeesData() ) ); } } import 'package:flutter/material.dart' import '../../models/model.dart' import '../../controllers/network_helper.dart' class HomeScreen extends StatefulWidget static const String "home_screen" static const String "Home" @override < > class _HomeScreenState extends State HomeScreen @override return Here, we are dealing with asynchronous data binding. When the app start, the widgets were built as immutable for performance reasons. Therefore, we need to let flutter know which widgets may change during the runtime. This is where state management takes place. In our app, we set as a stateful widget. This gives flutter information that may need to rebuild during runtime. In this case, will receive data that we fetched previously. But we need a method to handle the data we receive. Take a look at the code below: HomeScreen HomeScreen HomeScreen FutureBuilder _employeesData(){ FutureBuilder< <Employees>>( future: GetEmployee().getEmployees(), builder: (BuildContext context, AsyncSnapshot< <Employees>> snapshot){ (snapshot.hasData) { <Employees> data = snapshot.data; _employees(data); } (snapshot.hasError) { Text( ); } CircularProgressIndicator(); }, ); } return List List if List return else if return " " ${snapshot.error} return Now, we create a widget that will be responsible to handle the asynchronous process, the . This widget will call the operation to fetch the data that we have created before, and as soon as the return value comes, it will call the function to build the widget to display our data. FutureBuilder ListView _employees(data) { ListView.builder( itemCount: data.length, itemBuilder: (context, index) { Card( child: _tile(data[index].employeeName, data[index].employeeSalary, Icons.work) ); } ); } ListTile _tile( title, subtitle, IconData icon) { ListTile( title: Text(title, style: TextStyle( fontWeight: FontWeight.w500, fontSize: , )), subtitle: Text(subtitle), leading: Icon( icon, color: Colors.blue[ ], ), ); } return return String String return 20 500 That's it! Please put a comment if you have any questions. The source of this article is available on github Thank you for reading!