Basic JSON String Parsing in Flutter.

Basic JSON String Parsing in Flutter.

Manual JSON Serialization

When developing network-connected apps, it is most likely that it will need to use some good old JSON at some point. It is hard to imagine a mobile app that doesn't need to communicate with a web server or store structured data.

The guide looks at how to use JSON with Flutter. It explains how to select the right JSON solution for each scenario and why.

If you are here, for learning how to do JSON Serialization in Flutter, you are at the right place. I will be walking you through all the concepts related to JSON.

Excited to learn??

Let's Get started...


We can perform JSON serialization manually or Automated Serialization using Code Generation in Flutter.

Hey but, what is JSON??

If you are a beginner, you will be wondering what the heck is JSON first of all?

JSON stands for JavaScript Object Notation. This doesn't mean you have to learn JavaScript or something, JSON is just a text-based format for representing data. It is fully independent of JavaScript.

You may ask if it is used for representing data then, Why is JavaScript in the Full-form?

Because it is using JavaScript object Syntax.

JSON is used for transmitting data in web applications.

For Example, You want some data from the server or you want to send some data on the server, here Json comes into play to help us.

You may ask, how does JSON look like?

{
    "College_Name": "No Name",
    "place": "SomeWhere on planet Earth",
    "formed": 2052,
    "active" : true,
    "students":[
        {
            "name": "name": {
              "title": "Mr",
              "first": "Gulshan",
              "last": "Yadav"
                },
            "roll_no": 32,
            "species" : "human"
        },
        {
            "name": {
              "title": "Mr",
              "first": "Rahul",
              "last": "Yadav"
            },
            "roll_no": 69,
            "species": "Martian"
        }
    ]
}

Now let's see how to manually parse this JSON string. Let's say we have a program which shows the information about the students. For starters, it shows some information about the college or school.
So my first step will be loading this JSON output from the source.
This could be anything, you can source your JSON file from the assets in the code or you may use any external API for that.

In this article, we will be learning how to do network calls to get the JSON data and how to parse it properly.

Step 1:

import ‘dart:convert’;

We need dart:convert so that we can use the JsonDecode function which will help us to map all our JSON into a variable.

Step 2:

Now create a variable of type const to store the address from where our program will fetch the JSON string.

const  myJsonSourceUrl = “https://mysourceofJson.com”; 
// Don’t use it, I wrote it for explaining to you.

Step 3: Create a class of any name of your choice.

For Example:

class NetworkService{

}

Step 4: Declare a async function of type Future of any Name of your choice.

class NetworkService{
Future fetchMyApi() async {
    http.Response response = await http.get(Uri.parse(myJsonSourceUrl));
       }
}


You may get an error message in your debug console, saying "hey man, idk what is this HTTP. Rectify the mistake."

So to fix it,

head over to your pubsec.yaml file and add http: ^0.13.3 under the dependencies section.

Dependencies

And then run flutter pub get in your terminal.
But wait this will not fix your error.

import http inside your program like this,

import 'package:http/http.dart' as http;

now you may see that your error got fixed.

Kudos!

If still your error not got fixed then re-run the command flutter pub get in your terminal and also check the pubsec.lock file to check if your dependencies or loaded or not.

My pubsec.lock file,

image.png

If still, you are facing any issue, then head over to our Telegram channel and throw some questions, I'll be happy to help you.

Hey but what does that Future data type used for, and what it is?

It is an object that represents delayed computation.

A Future is used to represent a potential value or error, that will be available at some time in the future.

There's more but, right now this much information is enough to get our job done :)

What are those await and async?

"Async Simply means occurring at the same time. And Await means to wait. i.e. to wait for a certain operation to over."


Here our program is fetching the JSON string from the source, And then storing it inside a variable of type http.Response.

Step 5: Check if the response is successful or not?

How do we do that?

It's simple but first of all, we need to know what is a successful response?
A successful response is a response with a status code of 200.
And a failed response is a response with a status code of anything other than 200.

So now we have to just check if the status code is 200 or not.
we can use our simple if-else loop or try-catch method.
For the sake of simplicity, we will be sticking with the if-else loop.

But how to check the status code?

Since we declared our variable of type http.Response, we can access the status code by using response.statusCode.

here's how our if-else loop will look like,

 if (response.statusCode == 200) {
      Map CollegeData = jsonDecode(response.body);
      // debugPrint(CollegeData.toString());
      List<dynamic> College = CollegeData["students"];
      return College.map((json) => students.fromJson(json)).toList();
    } else {
      throw Exception("Something gone wrong, ${response.statusCode}");
    }

Let's break it down,

As we know the first line of our code checks if the status code is 200 or not. if it is 200 then it will execute the next line of code.

i.e. Map myData = jsonDecode(response.body);

This maps the json string into a variable of type Map.

What is a Map?

A Map is a collection of key-value pairs.

It is similar to a dictionary in python.
It is also similar to a hashmap in java.
It is also similar to a hashtable in c++.


Now we have to access the values of the Map. And we can do that by using the [] operator.


Here we are storing the value of the students key into a variable of type List<dynamic>.
Then we are mapping the values of the List<dynamic> into a List<Student>.

student_network_service.dart

import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:network_request/model/student.dart';

const String randomPersonURL = "https://linktoapi.com"; // Just an example.

class StudentNetworkService {
  Future<List<Students>> fetchStudents(int amount) async {
    http.Response response = await http.get("$randomPersonURL?results=$amount");

    if (response.statusCode == 200) {
      Map peopleData = jsonDecode(response.body);
      List<dynamic> peoples = peopleData["results"];
      return peoples.map((json) => Students.fromJson(json)).toList();
    } else {
      throw Exception("Something gone wrong, ${response.statusCode}");
    }
  }
}

But wait where's the code for the Student class?
At this point, you might have a clear understanding of how manual JSON parsing works.

If not then, hang on. I will be explaining it in detail.
Step 6:
Now we have to create a class of type Student. But where?
Create a folder named model and put it inside the lib folder.

Create a file inside the model folder and name it as student.dart.

Note: Use lower came case for naming the file. To avoid any errors.
Also, don't use any special characters in the file name.

Create a class named student. (As we have used student in our above code, we will use it here too.)
What we want our code to do is to parse the JSON string, to get the student's information to show up in a list on the homepage.

So our code will look like this,

model/student.dart

class Students {
  String name;
  String rollNo;
  String species;

  Students({this.name, this.rollNo, this.species});

  Students.fromJson(Map<String, dynamic> json)
      : name =
            "${json["name"]["title"]} ${json["name"]["first"]} ${json["name"]["last"]}",
        rollNo = json["roll_no"],
        species = json["species"];
}

Have a look at the code.

First of all, we are creating a constructor.
Then we are creating a method named fromJson.
And inside the method, we are parsing the JSON string and storing the values in the variables.

So that's it, we performed the manual JSON parsing.

Here's how we will use this class in our code,

homepage.dart

import 'package:flutter/material.dart';
import 'package:network_request/model/student.dart';
import 'package:network_request/services/student_network_service.dart';

class HomeScreen extends StatelessWidget {
  final StudentNetworkService studentService = StudentNetworkService();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: SafeArea(
          child: FutureBuilder(
            future: studentService.fetchStudents(100),
            // 100 is the number of students to fetch, But you can change the fetchStudents function to 
            // use the json file in your assets too.
            builder:
                (BuildContext context, AsyncSnapshot<List<Students>> snapshot) {
              if (snapshot.hasData) {
                return Row(
                  children: <Widget>[
                    Expanded(
                      child: Container(
                        child: Card(
                          color: Colors.black.withOpacity(0.5),
                          child: ListView.builder(
                              itemCount: snapshot.data.length,
                              itemBuilder: (BuildContext context, int index) {
                                var currentStudent = snapshot.data[index];

                                return ListTile(
                                  title: Text(currentStudent.name),
                                  leading: CircleAvatar(
                                      // Left for you to do experiments.

                                      // backgroundImage:
                                      //     NetworkImage(currentStudent.),
                                      ),
                                  subtitle:
                                      Text("Roll no: ${currentStudent.rollNo}"),
                                );
                              }),
                        ),
                      ),
                    ),
                  ],
                );
              }

              if (snapshot.hasError) {
                return Center(
                    child: Icon(
                  Icons.error,
                  color: Colors.red,
                  size: 82.0,
                ));
              }

              return Center(
                  child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  CircularProgressIndicator(),
                  SizedBox(
                    height: 20.0,
                  ),
                  Text("Loading at the moment, please hold on")
                ],
              ));
            },
          ),
        ),
      ),
    );
  }
}

Now let's see how we can do that using the json_serializable package to implement the same but by a single line of code. Not a single line of code, but lesser than usual.

Our whole tedious task will be handled by the flutter engine.

Check this post.


Today we learned how to parse the JSON string and store the values in the variables in flutter.
Our next post will guide you on how to generate the dart code so that it can be used to parse the JSON string with a working example.

Reducing the possible errors and bugs.

Until then, Happy Coding :)

Did you find this article valuable?

Support Gulshan Yadav by becoming a sponsor. Any amount is appreciated!