Flutter - Fetching JSON Data using HTTP
In this article, we will learn how to fetch data from the internet or JSON file using the HTTP package in a flutter.
What is HTTP?
The HTTP is a composable, future-based library for making HTTP requests. This package contains a set of high-level functions and classes that make it easy to consume HTTP resources. It's multi-platform and supports mobile, desktop, and browser.
Step By Step Implementation
Step 1: Create a new Flutter Application
Create a new Flutter application using the command Prompt. To create a new app, write the below command and run it.
flutter create app_name
To know more about it refer this article: Creating a Simple Application in Flutter.
Step 2: Adding the Dependency
To add the dependency to the pubspec.yaml file, add http as a dependency in the dependencies part of the pubspec.yaml file, as shown below:
dependencies:
flutter:
sdk: flutter
http: ^1.3.0
Now run the below command in the terminal.
flutter pub get
Or
Run the below command in the terminal.
flutter pub add http
Step 3: Working with main.dart
Add the boilerplate code below in main.dart to create a basic structure with an AppBar and body using a Scaffold.
import 'package:flutter/material.dart';
import 'package:workingwithhttp2/MyApi.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "MyApi",
debugShowCheckedModeBanner: false,
home: MyApi(),
);
}
}
class MyApi extends StatefulWidget {
@override
_MyApiState createState() => _MyApiState();
}
class _MyApiState extends State<MyApi> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Geeks for Geeks"),
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
body: // Code Here
);
}
}
Step 4: Initialize variables
Intialize required variables.
// Future to hold the API response
late Future<List<dynamic>> response;
@override
void initState() {
super.initState();
// Fetch users when the widget is initialized
response = fetchUsers();
}
Step 5: Create methods
Create methods to to fetch user data from the API using the http package.
// Function to fetch user data from the API
Future<List<dynamic>> fetchUsers() async {
// API call
final result = await http.get(
Uri.parse("https://randomuser.me/api/?results=20"),
);
// Parse and return the results
return jsonDecode(result.body)['results'];
}
Step 6: Develop UI
- myApiWidget: It to display API data using FutureBuilder.
// Widget to display API data using FutureBuilder
Widget myApiWidget() {
return FutureBuilder(
// Future to wait for
future: response,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// Show loading indicator while waiting for data
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
// Display data when available
return ListView.builder(
// Number of items in the list
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
// Get user data at the current index
var user = snapshot.data[index];
return Card(
margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: ListTile(
// User's profile picture
leading: CircleAvatar(
backgroundImage: NetworkImage(user['picture']['large']),
),
// User's full name
title: Text(
"${user['name']['title']} ${user['name']['first']} ${user['name']['last']}",
),
// User's email
subtitle: Text(user['email']),
// User's age
trailing: Text(user['dob']['age'].toString()),
),
);
},
);
} else if (snapshot.hasError) {
// Display error message if an error occurs
return Center(child: Text("Error: ${snapshot.error}"));
} else {
// Display message if no data is found
return Center(child: Text("No Data Found"));
}
},
);
}
Complete Source Code
main.dart:
import 'dart:convert';
// For JSON encoding and decoding
import 'package:flutter/material.dart';
// HTTP package for making API requests
import 'package:http/http.dart' as http;
void main() {
// Entry point of the application
runApp(MyApp());
}
// Main application widget
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "MyApi",
debugShowCheckedModeBanner: false,
// Set the home screen to MyApi widget
home: MyApi(),
);
}
}
// Stateful widget to handle API data fetching and display
class MyApi extends StatefulWidget {
@override
_MyApiState createState() => _MyApiState();
}
class _MyApiState extends State<MyApi> {
// Future to hold the API response
late Future<List<dynamic>> response;
@override
void initState() {
super.initState();
// Fetch users when the widget is initialized
response = fetchUsers();
}
// Function to fetch user data from the API
Future<List<dynamic>> fetchUsers() async {
final result = await http.get(
Uri.parse("https://randomuser.me/api/?results=20"),
); // API call
// Parse and return the results
return jsonDecode(result.body)['results'];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Geeks for Geeks"),
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
// Body of the screen
body: myApiWidget(),
);
}
// Widget to display API data using FutureBuilder
Widget myApiWidget() {
return FutureBuilder(
// Future to wait for
future: response,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// Show loading indicator while waiting for data
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
// Display data when available
return ListView.builder(
// Number of items in the list
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
// Get user data at the current index
var user = snapshot.data[index];
return Card(
margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: ListTile(
// User's profile picture
leading: CircleAvatar(
backgroundImage: NetworkImage(user['picture']['large']),
),
// User's full name
title: Text(
"${user['name']['title']} ${user['name']['first']} ${user['name']['last']}",
),
// User's email
subtitle: Text(user['email']),
// User's age
trailing: Text(user['dob']['age'].toString()),
),
);
},
);
} else if (snapshot.hasError) {
// Display error message if an error occurs
return Center(child: Text("Error: ${snapshot.error}"));
} else {
// Display message if no data is found
return Center(child: Text("No Data Found"));
}
},
);
}
}