Part 4. Handling Networking to Retrieve Real Data

Firebase

We will proceed with the next step, which is retrieving the list of questions from the backend and displaying them accordingly.

I.Reorganizing the REST API Library

1.Creating a Demo API to Return Data with Express.js Server

To obtain data from the API, let's quickly create an Express.js server and return the response as follows::

2. Define the Basic Response

The data after calling the API can have success/failure scenarios. Correspondingly, we will create a ServiceResponse model to define it.

In the ServiceResponse, we can observe: 

3. Wrapping the REST API Calling Library

In Flutter, to connect to an API, we use the dio library: https://pub.dev/packages/dio

The first thing to do when dealing with networking is to wrap the dio library into a base class for handling. This is not only applicable to networking but also to many other types of handling. Why do we need to do this? It's because at some point, we may want to use a different library to replace it. Wrapping the original library into a utils class helps avoid unnecessary changes later on. It also allows us to handle exceptions in a centralized manner.

The wrapped dio in utils will look like this: 

Here, I'm wrapping the get method and handling basic dio exceptions, returning an error response. If you have specific requirements to handle different exception cases according to the task requirements, you can refer to advanced Flutter topics on building a base.

II.Basic State Management

1.Calling API to Fetch Data

After completing the basic networking part, let's return to the home screen. We observe that on this screen, there is data about the list of questions. This is the state, and to manage it, Flutter provides various mechanisms. I will introduce using Bloc Cubit, but first, let's start with basic state management in Flutter with StatefulWidget.

In the HomeScreen, we switch to a StatefulWidget to call the API, fetch the question data, and display it.

Run the project again, and if we print the data, we should see it:

So, with a successful API call, we now have data about the list of questions.

2.Casting the data received from the API into an object model

To use the data, we need to build an object model for the questions and cast the received data into that model.

In the model, we define values such as number, result, picture, suggest corresponding to the data returned from the API. You'll also see the fromJson function, which helps us convert data from JSON to an object. Now that we have created the model, let's proceed to casting the data and modifying the getListQuestion() function:

Next, let's run the debug and check each value at each step:

Checking response.data, we can see that the API has returned 9 questions, and the data is currently a List of Maps, with each Map containing the data for one question.


Checking the next statement: here, we iterate through the array of questions above, calling QuestionModel.fromJson(json) to cast it to QuestionModel. We can see that at this point, the data type for the questions is no longer a Map but has been cast to the correct QuestionModel.

This ensures that the data is converted to the corresponding object.

3.setState

To notify the UI that the state has changed, we use setState. Let's update the list of questions loaded from the API for the HomeScreen:

After setState, the build function will be called, and the UI will be redrawn. Consequently, the list of questions will be displayed accordingly.

III. Summary

Through this tutorial, we have built the basic structure of base_network, retrieved data from the API, and converted it into an object model that can be used in the app. Additionally, we have understood the basics of state management in Flutter.