Consuming API's with Flutter & Dart

Consuming API's with Flutter & Dart

API's

API's are used a lot today in the world of software development as we all understand that it is an awesome interface for making cross-platform applications sync perfectly and work together.

This article will guide you through easy steps in consuming API's as streams using Flutter & Dart I'm sure you will find it very easy to understand.

First of all, let's think of an API as a menu where all the dishes you can order in the restaurant are listed, along with the description of each dish. When you specify what menu items you want, the restaurant’s kitchen does the work and provides you with some finished dishes. You don’t know exactly how the restaurant prepares that food, and you don’t really need to.

That is basically how an API's works too, API's list out a bunch of operations that a developer can use alongside the description of what they do. The developer doesn’t really need to know-how. They just need to know that it's available for use in their app.

stream_no_listener.gif

What are Streams?

Asynchronous programming in Dart is characterized by the Future and Stream classes.

  • Streams provide an asynchronous sequence of data -> Data sequences include user-generated events and data read from files.
  • You can process a stream using either await for or listen() from the Stream API.
  • Streams provide a way to respond to errors.

api.dartlang.org

There are two kinds of streams: single subscription or broadcast.


In this article, we will be making use of subscription stream to consume API from a remote data source

API End-point jsonplaceholder.typicode.com/posts

below is what the response looks like.

[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
 ........
]

:memo: Required flutter packages.

[*] A composable, Future-based library for making HTTP requests. http

We will be using models to represent the response data in this article Let's create a file posts.dart where the model of our post response will reside.

class Post{
    int userid;
    int id;
    String title;
    String body;

     Post()

    Post.fromJSON(Map<String,dynamic> jsonMap){
        userid = jsonMap['userid'];
        id = jsonMap['id'];
        title = jsonMap['title'];
        body = jsonMap['body']
    }
}

The above class contains the skeletal structure of the data that would be received from the API endpoint.

import 'dart:convert';

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

import 'package:restaurant_rlutter_ui/src/models/posts.dart';

Future<Stream<Post>> getPosts() async {
  final String url = "https://jsonplaceholder.typicode.com/posts";
  final client = new http.Client();
  final streamedRest = await client.send(http.Request('get', Uri.parse(url)));

  return streamedRest.stream
      .transform(utf8.decoder)
      .transform(json.decoder)
      .map((data) => data)
      .expand((data) => (data as List))
      .map((data) {
    return Posts.fromJSON(data);
  });
}

The above snippet is a future that returns a stream of Posts from the stated endpoint.


 List<Post> posts = <Post>[];

 void listenForPosts() async {
    final Stream<Post> stream = await getPosts();
    stream.listen((Post _post) {
      setState(() {
          posts.add(_post)
    });
    }, onError: (a) {
      print(a);
      scaffoldKey.currentState?.showSnackBar(SnackBar(
        content: Text('Verify your internet connection'),
      ));
    }, onDone: () {

       // Do anything
      }
    });
  }

The above function processes the stream using listen() from the Stream API.