Fetch Data from the Internet with Flutter.
Tags: flutter, dart
Published: 2021-04-26 16:17:12

**This article was posted in my [Blog](https://yassine-bennkhay.tech/) also, so I'll be happy if you check it out :)**
Most apps need to deal with the internet and fetching data from it is necessary. Flutter and Dart provide tools such as the [http](https://pub.dev/packages/http) package regarding this matter. to fetch data and display it in your app there're steps we'll follow and they're the following:

- add the http package
- make a network request using http package
- convert the response into a Dart object
- Fetch and display data with Flutter 

In this article I'm going to use  [JSONPlaceholder](https://jsonplaceholder.typicode.com/) to fetch a Post using  [http.get( )](https://pub.dev/documentation/http/latest/http/get.html) method. So let's get Started!

**1-add the http package:**
in the pubspec.yaml file adds the latest version of the  [http package](https://pub.dev/packages/http) and get dependencies.
```
dependencies:
  http: <latest_version>

``` 
**2-make a network request using http package:** 
we create a method of type ** Future of http.Response**. then we store the Response we get from our **http.get( )** method in the gettedPost variable .then we check if the gettedPost has data or not through the if statement as you can see in the code snippet below.

```
Future<http.Response> getPostDetails()async{
    http.Response gettedPost=
    await http.get(Uri.https('jsonplaceholder.typicode.com', 'posts/1'),);
    if(gettedPost.statusCode==200){
      //success
print(futurePost.body);//just printing out the data in the console for now!
      return null;
    }else{
//failed for some reason.
      throw Exception('we cant load your data ');
    }
  }
``` 
for testing purposes, I printed out the response in the console first :)


![carbon (2).png](https://cdn.hashnode.com/res/hashnode/image/upload/v1619448878832/3YE4LbgJQ.png)

**3-Convert the response into a custom Dart object**:

the **http.Response** class contains the data received from a successful http call, however, we need to convert it to a custom dart object so we make life easier for us!
for that, we create a Post class that contains the data from the network request.
The Post class contains a  [factory constructor](https://dart.dev/guides/language/language-tour#factory-constructors) to create a Post.

```
class Post{
  int userId;
      int id;
  String title;
  String body;
  Post({this.body,this.title,this.id,this.userId});
factory Post.fromJson(Map<String,dynamic>comingJson){
  return Post(
    id: comingJson['id'],
    userId: comingJson['userId'],
    title: comingJson['title'],
    body: comingJson['body'],
  );
}
}
``` 
now we need to convert the http.Response to a Post using the dart:convert 
and update the *getPostDetails( )* to return a *Future of Post*.
If the server does return an OK response with a status code of 200, then convert the JSON Map into a Post using the fromJson() factory method.

If the server does not return an OK response with a status code of 200, then throw an exception.

```
import 'dart:convert';
  Future<Post> getPostDetails()async{
    http.Response futurePost=
    await http.get(Uri.https('jsonplaceholder.typicode.com', 'posts/1'),);
    if(futurePost.statusCode==200){
    /*if the server return an Ok status code 200 then convert the JSON Map into a Post*/
      return Post.fromJson(jsonDecode(futurePost.body));
    }else{
      /*if the server did not return an status code then throw exception*/
      throw Exception('we cant load your data ');
    }
  }
``` 
Great till now, we're quite close!
**4-Fetch & Display Data:**

to Fetch the data we create a variable to hold the getPostDetails( ) in the initState() method like this:

```
 Future<Post> postData;
@override
  initState(){
super.initState();
postData=getPostDetails();
  }
``` 
the last thing is to display the data in the user interface and for that, we'll use  [ FutureBuilder](https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html) widget and give it the future parameter you want to work with, in this case, getPostDetails( ) and the builder function that tells Flutter what to render.

```
FutureBuilder(
          future: postData,
          builder: (context,snapShot){
           if(snapShot.hasData){
             return Padding(
               padding: const EdgeInsets.all(8.0),
               child: Column(
                 children: [
               Text('the user id is: ${snapShot.data.userId}'),
                   Text('the id is : ${snapShot.data.id}'),
                   Text('the title is : ${snapShot.data.title}'),
                   Text('the body is: ${snapShot.data.body}'),
                 ],
               ),
             );
           }else if(snapShot.hasError){
             return Text("${snapShot.error}");
           }
           return CircularProgressIndicator();
          },
        ),
``` 

#### The Complete Example:
##### The Post Model:

```
class Post{
  int userId;
      int id;
  String title;
  String body;
  Post({this.body,this.title,this.id,this.userId});
factory Post.fromJson(Map<String,dynamic>comingJson){
  return Post(
    id: comingJson['id'],
    userId: comingJson['userId'],
    title: comingJson['title'],
    body: comingJson['body'],
  );
}
}
``` 
##### main ( ):

```
import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart 'as http;

import 'model/post.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  Future<Post> postData;
@override
  initState(){
super.initState();
postData=getPostDetails();
  }
  Future<Post> getPostDetails()async{
    http.Response futurePost=
    await http.get(Uri.https('jsonplaceholder.typicode.com', 'posts/1'),);
    if(futurePost.statusCode==200){
    /*if the server return an Ok status code 200 then convert the JSON Map into a Post*/
      return Post.fromJson(jsonDecode(futurePost.body));
    }else{
      /*if the server did not return an status code then throw exception*/
      throw Exception('we cant load your data ');
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
appBar: AppBar(title: Text('getting data from the internet.'),),
      body: Center(
        child:FutureBuilder(
          future: postData,
          builder: (context,snapShot){
           if(snapShot.hasData){
             return Padding(
               padding: const EdgeInsets.all(8.0),
               child: Column(
                 children: [
               Text('the user id is: ${snapShot.data.userId}'),
                   Text('the id is : ${snapShot.data.id}'),
                   Text('the title is : ${snapShot.data.title}'),
                   Text('the body is: ${snapShot.data.body}'),
                 ],
               ),
             );
           }else if(snapShot.hasError){
             return Text("${snapShot.error}");
           }
           return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

``` 
Alright! that was how to fetch a simple Post from the Internet with Flutter.

❤ ❤ Thanks for reading this article ❤❤

Please If I got something wrong? Let me know in the comments. I would love to improve!
if you find this article helpful click that like button and don't forget to check my [Instagram](https://www.instagram.com/yassine_dev1/) for more Content about Flutter❤