Writing Methods to Fetch Comics

A consideration has to be done before continuing with the implementation: the optimal data type to store comics is Map<String, dynamic>, which handles JSON objects perfectly.

Given that we know how to fetch comics, let’s start writing some code to use that knowledge to write methods to fetch comics that we can use in our app!

Fetching the Latest Comic

Wrapping the code we discussed earlier into an arrow function isn’t hard at all:

 Future<Map<​String​, ​dynamic​>> fetchLatestComic() async =>
  json.decode(
  await http.read(​"https://xkcd.com/info.0.json"​)
  );

We can access a Map’s field a lot like we would access List elements by using varName["attrName"] where varName is the name of the Map variable and attrName is the name of the attributes. This is exactly the same syntax used in Python to access dictionary elements. This is how you access every attribute:

 var​ comic = fetchLatestComic();
 int​ ​num​ = comic[​"num"​];
 String​ link = comic[​"link"​];
 String​ news = comic[​"news"​];
 String​ safe_title = comic[​"safe_title"​];
 String​ transcript = comic[​"transcript"​];
 String​ alt = comic[​"alt"​];
 ImageProvider img = NetworkImage(comic[​"img"​]);
 String​ title = comic[​"title"​];
 String​ MDYDate = ​"​​${comic["month"]}​​/​​${comic["day"]}​​/​​${comic["year"]}​​"​;
 String​ DMYDate = ​"​​${comic["day"]}​​/​​${comic["month"]}​​/​​${comic["year"]}​​"​;

Fetching Previous Comics

Fetching by comic number is easy since the API is designed to do just that:

 Future<Map<​String​, ​dynamic​>> fetchComic(​int​ n) async =>
  json.decode(
  await http.read(​"https://xkcd.com/info.0.json"​)
  );

But sorting reverse chronological is a lot harder, as we need to know the latest comic number to get the previous, and so on:

 Future<Map<​String​, ​dynamic​>> fetchComic(​int​ n) async {
 int​ latestComicNum = ...;
 return​ json.decode(
  await http.read(​"https://xkcd.com/info.0.json"​)
  );
 }

The obvious way to do that would be to just call fetchLatestComic and get the num attribute, like this:

 int​ latestComicNum = fetchLatestComic()[​"num"​];

But doing it that way would require two different GET requests to fetch each comic, and many of them are going to be redundant and useless.

Fetching the Latest Comic Number Just Once

Since we are going to use these methods inside an app, which will have a wrapper class around it (at least for the home screen), we can just pass it to that class when we run the app and then the fetchComic method inside that class will be able to access it directly.

The New fetchComic

Fetching a comic is really simple this way, since we don’t need to worry about the latest comic number, which will be provided by the class in which we’ll define the method:

 Future<Map<​String​, ​dynamic​>> fetchComic(​int​ n) async =>
  json.decode(
  await http.read(
 "https://xkcd.com/​​${latestComicNum-n}​​/info.0.json"
  )
  );

A Function to Get the Latest Comic Number

We need to get the latest comic number when we run the app though, and to do that we need to define a function that will fetch that when we need it:

 Future<​int​> getLatestComicNumber() async =>
 json.decode(
  await http.read(​'https://xkcd.com/info.0.json'​)
  )
  [​"num"​];

What If There’s No Internet Connection?

If there is no Internet connection, the app will not work. This is a problem but, since we are downloading all of the comics anyway, we should be able to fix it just by saving them to permanent local storage so that we can load them when there is no Internet connection.

This has the added advantage of giving us the chance to optimize our app in a significant way: if we have the previous comics on local storage we don’t need to fetch them from the Internet, so we finally eliminate all the redundant GET requests and we can just focus on getting new data when we need it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset