Professional Documents
Culture Documents
How To Do Networking Like A Pro in Flutter - The Startup - Medium
How To Do Networking Like A Pro in Flutter - The Startup - Medium
You have 1 free member-only story left this month. Sign up and get an extra one for free.
Dhananjay Trivedi
Apr 25 · 7 min read
When I started learning Networking for the first time in Android there was a lot of
things involved like
Adding some Networking library like Volley or Retrofit or write some more
boilerplate code with the Http
It was painful.
A little bit about State Management using Provider Package. [Quick Read]
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 2/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
dev_dependencies:
flutter_test:
sdk: flutter
http: ^0.12.0+4
provider_architecture: ^1.0.5
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 3/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
JSON to Dart
Paste your JSON in the textarea below, click convert and get your Dart classes for free.
javiercbk.github.io
Paste your Json Data in the Left field and give name of your Model Class in the field
below. I have given APIResponseModel
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 4/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
Back in your project, create a new Dart file and give it a name, I have given
api_response_mode.dart and copy paste your Dart Code.
This is the starter code for this UI. Make sure you call HomeScreen() from your
main.dart .
1 import 'dart:convert';
2
3 import 'package:flutter/cupertino.dart';
4 import 'package:flutter/material.dart';
5 import 'package:http/http.dart' as http;
6
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 5/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
6
7 import 'api_response_model.dart';
8
9 class HomeScreen extends StatefulWidget {
10 @override
11 _HomeScreenState createState() => _HomeScreenState();
12 }
13
14 class _HomeScreenState extends State<HomeScreen> {
15 APIResponseModel apiResponseModel;
16 bool isLoading = false;
17
18 @override
19 Widget build(BuildContext context) {
20 return Container(
21 color: Colors.white,
22 child: SafeArea(
23 child: Scaffold(
24 appBar: AppBar(
25 title: Text("Networking Example"),
26 ),
27 body: Container(child: Center(child: buildDataWidget())),
28 floatingActionButton: FloatingActionButton(
29 child: isLoading
30 ? CircularProgressIndicator(
31 backgroundColor: Colors.white,
32 )
33 : Icon(Icons.cloud_download),
34 tooltip: "Get Data from API",
35 onPressed: () => getDataFromAPI(),
36 ),
37 )));
38 }
39
40 void getDataFromAPI() async {
41 setState(() {
42 isLoading = true;
43 });
44 const String API_URL = "https://corona.lmao.ninja/v2/all";
45 var response = await http.get(Uri.parse(API_URL));
46 var parsedJson = await json.decode(response.body);
47 setState(() {
48 apiResponseModel = APIResponseModel.fromJson(parsedJson);
49 isLoading = false;
50 });
51 }
52
53 buildDataWidget() {
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 6/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
54 if (apiResponseModel == null)
55 return Container(
56 child: Padding(
57 padding: const EdgeInsets.all(16.0),
58 child: Text(
59 "Press the floating action button to get data",
60 style: TextStyle(fontSize: 24),
61 textAlign: TextAlign.center,
62 ),
63 ),
64 );
65 else {
66 return Text(
67 "Total Cases : ${apiResponseModel.cases}\n"
68 "Today's Cases : ${apiResponseModel.todayCases}\n"
69 "Total Deaths : ${apiResponseModel.deaths}\n"
70 "Today's Deaths : ${apiResponseModel.todayDeaths}\n"
71 "Total Recovered : ${apiResponseModel.recovered}\n"
72 "Active Cases : ${apiResponseModel.active}\n"
73 "Critical Cases : ${apiResponseModel.critical}\n"
74 "Cases per million: ${apiResponseModel.casesPerOneMillion}\n"
75 "Deaths per million: ${apiResponseModel.deathsPerOneMillion}\n"
76 "Total Tests Done: ${apiResponseModel.tests}\n"
77 "Tests per million: ${apiResponseModel.testsPerOneMillion}\n"
78 "Affected countires : ${apiResponseModel.affectedCountries}\n",
79 style: TextStyle(fontSize: 18),
80 );
81 }
82 }
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 7/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
setState will rebuild the widget with updated apiResponseModel data object. So we
can use it’s value inside our Text widget to show information which is inside
buildDataWidget()
But in beginning apiResponseModel will be null, which will make our app crash.
Hence, we need to check
if(apiResponseModel == null)
return Text("Default Text");
else
return Text("The data values");
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 8/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
That’s it!
Here is the complete code in action so far. I have added a Progress bar as well, to
make it a little better 😇
Please note : I have not taken care of error cases from the API or
some exception handling during the networking in parsing.
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 9/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
And the code isn’t very complex as well. But as the app complexity increases, the
number of functions and the number of setState() will only increase over time
making your code:
Harder to maintain
Harder to change
There are a set of principles called SOLID Principles which can help you design better
application architecture.
One of the most popular rule is the Single Responsibility Principle which encourages
you to minimize the amount of responsibility a function / class as to 1.
We will try to minimize the responsibility of our UI, ie, HomeScreen with a better
design.
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 10/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
1 The UI or
The data for the UI will be stored inside the ViewModel, and as the ViewModel data
updates, the UI will also rebuild itself accordingly to show the latest data in the view
model.
Remember, ViewModel is only responsible for storing the data and doesn’t care
where the data is coming from. ViewModel just gets the data and stores it in the
ViewModel.
In our current example, data is coming only from one source that is the API. But when
you will be building even a bit complex app, you might be dealing with multiple data
sources like OfflineCache, Offline Database, FileStorage.
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 11/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
You shouldn’t expect your ViewModel to call and delegate each one of these, your
repository will be managing the data from these different sources for your ViewModel.
If in future, you want to swap an OfflineCaching system with a database, you only will
have to make the updates in your Repository class without having to touch your UI or
ViewModel.
4 Separate Repositories will be setup for each of the data sources of your
application.
Each repository will be responsible for managing data from each source. For example
NetworkRepository will contain code for Networking through http while there will be
a separate FirebaseRepo for managing your Firebase related logic. If you have offline
caching, you will create a repo for that as well. I hope you get the picture.
Pro Tip:
. . .
1. First thing you have to do is to remove the two state fields from the HomeScreen()
Widget.
2. Then, Create your ViewModel and add those two fields inside the viewmodel.
1 import 'package:flutter/cupertino.dart';
2 import 'package:networking_like_a_boss/model/networking_response.dart';
3 import 'package:networking_like_a_boss/screens/home/home_repository.dart';
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 12/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
4 import '../../model/api_response_model.dart';
5
6 class HomeScreenViewModel extends ChangeNotifier {
7 HomeScreenViewModel() {
8 /// As soon as VM initializes
9 /// We want to get the latest data
10 getDataFromAPI();
11 }
12
13 APIResponseModel apiResponseModel;
14 String messageToShow = "";
15 bool isLoading = false;
16
17 void getDataFromAPI() async {
18 /// Start showing the loader
19 isLoading = true;
20 notifyListeners();
21
22 /// Wait for response
23 NetworkingResponse networkingResponse =
24 await HomeScreenRepository().getLatestStatsData();
25
26 /// We check the type of response and update the required field
27 if (networkingResponse is NetworkingResponseData) {
28 /// Updating the APIResponseModel when success
29 apiResponseModel = networkingResponse.apiResponseModel;
30 } else if (networkingResponse is NetworkingException) {
31 /// Updating the errorMessage when fails
32 messageToShow = networkingResponse.message;
33 }
34
35 /// Stop the loader
36 isLoading = false;
37 notifyListeners();
38 }
39 }
1 import 'package:networking_like_a_boss/model/api_response_model.dart';
2 import 'package:networking_like_a_boss/model/networking_response.dart';
3 import 'package:networking_like_a_boss/repo/network_repo/NetworkRepo.dart';
4
5 class HomeScreenRepository {
6 /// ViewModel calls its Repository to getLatestStatsData
7 /// The Repository will take care of getting the data from thr right source
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 13/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
4. Add NetworkRepo Class , also, earlier we didn’t took care for Exception Handling. We
will do that now in a Cleaner way!
1 import 'dart:convert';
2
3 import 'package:http/http.dart' as http;
4 import 'package:networking_like_a_boss/model/api_response_model.dart';
5 import 'package:networking_like_a_boss/model/networking_response.dart';
6 import 'package:networking_like_a_boss/utils/constants.dart';
7
8 /// Network Repo will do the networking for you
9 /// And will also take care of parsing
10 /// and exception handling
11 /// will simply return you data model or the exception message
12
13 class NetworkRepo {
14
15 /// Instead of returning ApiResponseModel
16 /// We have created a parent class called NetworkingResponse
17 /// Which takes care of Successful and Failed response
18 /// So we either send a successful or failed response wrapped in NetworkingResponse
19
20 Future<NetworkingResponse> getLatestDataFromAPI() async {
21 try {
22 var response = await http.get(Uri.parse(API_END_POINT_URL));
23 var parsedJson = await json.decode(response.body);
24 APIResponseModel apiResponseModel = APIResponseModel.fromJson(parsedJson);
25 return NetworkingResponseData(apiResponseModel);
26 } catch (exception) {
27 return NetworkingException(exception.toString());
28 }
29 }
30 }
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 14/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
5. Finally just add the setup the ViewModel Provider and listen to the required fields in
the HomeScreen Widget.
As soon as the app starts, the HomeScreen ViewModel get initialized and the app get’s
latest data for the user without having to click on the button.
1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter/material.dart';
3 import 'package:networking_like_a_boss/screens/home/home_screen_view_model.dart';
4 import 'package:provider_architecture/provider_architecture.dart';
5
6 import '../../model/api_response_model.dart';
7
8 class HomeScreen extends StatelessWidget {
9 @override
10 Widget build(BuildContext context) {
11 return ViewModelProvider<HomeScreenViewModel>.withConsumer(
12 viewModel: HomeScreenViewModel(),
13 builder: (context, viewModel, child) {
14 return Container(
15 color: Colors.white,
16 child: SafeArea(
17 child: Scaffold(
18 appBar: buildAppBar(),
19 body: buildBody(viewModel),
20 floatingActionButton: buildFloatingActionButton(viewModel),
21 )));
22 });
23 }
24
25 AppBar buildAppBar() {
26 return AppBar(
27 title: Text("Networking Like a Pro"),
28 );
29 }
30
31 Widget buildBody(viewModel) {
32 /// building our UI
33 /// notice we are observing viewModel.apiResponseModel
34 /// Hence buildDataWidget will rebuild when apiResponse changes in ViewModel
35 return Container(child: Center(child: buildDataWidget(viewModel)));
36 }
37
38 FloatingActionButton buildFloatingActionButton(viewModel) {
39 return FloatingActionButton(
40 child: viewModel.isLoading
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 15/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
41 ? CircularProgressIndicator(
42 backgroundColor: Colors.white,
43 )
44 : Icon(Icons.cloud_download),
45 tooltip: "Get Data from API",
46
47 /// Calling our viewModel function
48 onPressed: () => viewModel.getDataFromAPI(),
49 );
50 }
51
52 buildDataWidget(viewModel) {
53 APIResponseModel apiResponseModel = viewModel.apiResponseModel;
54
55 if (apiResponseModel == null)
56 return Container(
57 child: Padding(
58 padding: const EdgeInsets.all(16.0),
59 child: Text(
60 "${viewModel.messageToShow}",
61 style: TextStyle(fontSize: 24),
62 textAlign: TextAlign.center,
63 ),
64 ),
65 );
66 else {
67 return Text(
68 "Total Cases : ${apiResponseModel.cases}\n"
69 "Today's Cases : ${apiResponseModel.todayCases}\n"
70 "Total Deaths : ${apiResponseModel.deaths}\n"
71 "Today's Deaths : ${apiResponseModel.todayDeaths}\n"
72 "Total Recovered : ${apiResponseModel.recovered}\n"
73 "Active Cases : ${apiResponseModel.active}\n"
74 "Critical Cases : ${apiResponseModel.critical}\n"
75 "Cases per million: ${apiResponseModel.casesPerOneMillion}\n"
76 "Deaths per million: ${apiResponseModel.deathsPerOneMillion}\n"
77 "Total Tests Done: ${apiResponseModel.tests}\n"
78 "Affected countires : ${apiResponseModel.affectedCountries}\n",
79 style: TextStyle(fontSize: 18),
80 );
81 }
82 }
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 16/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
I create a screens package and inside I group each screen with its UI, ViewModel
and Repo inside one package only.
repo contains the data source repositories and not the screen repositories.
Again, there is no hard and fast rule to structure your project this way. It’s just what I
prefer for this project.
devDeejay/FlutterNetworkingLikeABoss
You can't perform that action at this time. You signed in with another tab or
window. You signed out in another tab or…
github.com
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 17/18
6/21/2020 How to do Networking like a Pro in Flutter? - The Startup - Medium
. . .
I would love to hear more from you, please reach out if you have any ideas for
improvements, feedback or suggestions.
https://medium.com/swlh/how-to-do-networking-like-a-pro-in-flutter-7e2612103cb5 18/18