How To Fetch API data in Flutter? RestAPI in Flutter
To fetch the data from API, we need a http package that calls our API endpoint. Then we will convert API json Data into our Dart Model class provide it into our app UI using Future Builder.
In this example, we will show you how to get data from API using flutter and show it to our app UI. After completing this article you will be able to handle any kind of REST API.
Add http Package to Dependency
First of all create an example project using
flutter create api_callNow add http dependency on it.
You can get the latest version of http dependency on pub.dev. Or add this on your dependency.
dependencies:http: ^0.13.4
Add INTERNET permission
In debug mode, they added internet permission on manifest. But for building our app we need to provide internet permission manually. For that go to.
android > app > src > main > AndroidManifest.xml
Copy and paste this line after package name.
<uses-permission android:name="android.permission.INTERNET"/>
Here is an image of adding internet permission to your App.
Create Json Model Class
In this article we will fetch photos and data from Json Placeholder API with our custom Model Class.
Open this link to see the json file we will receive after calling this API. You will see a list like this.
{
"albumId": 1,
"id": 1,
"title": "accusamus beatae ad facilis cum similique qui sunt",
"url": "https://via.placeholder.com/600/92c952",
"thumbnailUrl": "https://via.placeholder.com/150/92c952"
}
Copy and Paste it into our Json to Dart Converter website, give a class name and copy the generated code. Now create a new file and name it jsonmodel.dart and paste them inside it. Code will look like this.
import 'dart:convert';
JsonPhoto jsonPhotoFromMap(String str) => JsonPhoto.fromMap(json.decode(str));
String jsonPhotoToMap(JsonPhoto data) => json.encode(data.toMap());
class JsonPhoto {
JsonPhoto({
required this.albumId,
required this.id,
required this.title,
required this.url,
required this.thumbnailUrl,
});
int albumId;
int id;
String title;
String url;
String thumbnailUrl;
factory JsonPhoto.fromMap(Map<String, dynamic> json) => JsonPhoto(
albumId: json["albumId"],
id: json["id"],
title: json["title"],
url: json["url"],
thumbnailUrl: json["thumbnailUrl"],
);
Map<String, dynamic> toMap() => {
"albumId": albumId,
"id": id,
"title": title,
"url": url,
"thumbnailUrl": thumbnailUrl,
};
}
Make an HTTP Request and Fetch Data
To fetch data from internet we will create a future function called fetchAlbum(). That function return API json file into Future<List<JsonPhoto>> using previously created Json map.
Here is a code snippet of API request function
Now we will initialize our function when our app start. For that we have to initialize this future function inside initstate.
Here is the code with initialization
Future<List<JsonPhoto>> fetchAlbum() async {
final response = await http
.get(Uri.parse('https://jsonplaceholder.typicode.com/photos'));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
return parsed.map<JsonPhoto>((json) => JsonPhoto.fromMap(json)).toList();
} else {
throw Exception('Failed to load album');
}
}
//TODO:Use Randaom Custom Colors
late Future<List<JsonPhoto>> futureAlbum;
@override
void initState() {
// TODO: implement initState
super.initState();
futureAlbum = fetchAlbum();
}
Show Data to UI using Future Builder
For showing Future Function data into our app we have to create a Future builder. Let's return Future builder as our main Widget which will return a Listview builder.
FutureBuilder<List<JsonPhoto>>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (_, index) => Container(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
padding: EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: CircleAvatar(
backgroundImage:
NetworkImage("${snapshot.data![index].url}"),
radius: 100,
),
title: Text(
"${snapshot.data![index].title}",
maxLines: 1,
style: TextStyle(
overflow: TextOverflow.ellipsis,
fontSize: 12.0,
),
),
trailing: const Icon(Icons.photo),
)),
),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);