Flutter HTTP


Flutter HTTP Tutorial and Examples.

How to perform various HTTP Requests in Flutter, and Classes involved in this package.

Let's start by discussing the Requests class.

Requests:

In Flutter, a HTTP request where the entire request body is known in advance is represented by the Request class.

This class does derive from the BaseRequest which directly derives from the Object class.

Here's it's inheritance hierarchy:

Object -> BaseRequest -> Request

Here's it's constructor:

Request(String method, Uri url)

That will create us a new HTTP Request.

You use the Request class if you want more fine grained control over your HTTP Requests. Otherwise there are more generic methods we can use depending on the request type.

1. HTTP GET Request

In Flutter, we can make a HTTP GET Request using the get() function. Here's it's definition:

Future<Response> get (dynamic url, {Map<String, String> headers});

The request is sent with the given headers to the given URL. As a URL you allowed to pass either a Uri or a String.

Then the get() function will automatically initialize a new Client when it's we make our HTTP GET request. On the hand as when our request is finished then it will close it as well. It's recommended that if you're planning on making multiple requests to the same server, then you use a single Client for all of those requests.

Implementation:

Future<Response> get(url, {Map<String, String> headers}) =>
  _withClient((client) => client.get(url, headers: headers));

Here's a real world implementation of the get() function to make a GET request to a server:

  final JsonDecoder _decoder = new JsonDecoder();

  Future<dynamic> get(String url) {
    return http.get(url).then((http.Response response) {
      final String res = response.body;
      final int statusCode = response.statusCode;

      if (statusCode < 200 || statusCode > 400 || json == null) {
        throw new Exception("Error while fetching data");
      }
      return _decoder.convert(res);
    });
  }

2. HTTP POST request

HTTP POST requests, generally mean you sending some data to the server. This is a common scenario and you do make this request probably on a daily basis, whether logging in to your account or filing your tax returns.

So Flutter and Dart provide us with an easy to mae them using the post() function/method.

The post() method is defined as follows:

Future<Response> post (dynamic url, {Map<String, String> headers,dynamic body,Encoding encoding})

This method will make a HTTP POST request with the given headers and body to the given URL. Again, that given URL can be a Uri or a String.

The body we are passing there is the request body. This can be:

  1. String.
  2. List.
  3. Map<String,String>

(a). String If it's a String, then it will be encoded using encoding and used as the body of the request. The content-type of the request will default to "text/plain".

(b) List

If the body is a List, then it's used as a list of bytes for the body of the request.

(c). Map<String,String>

If body is a Map, it's encoded as form fields using encoding. The content-type of the request will be set to "application/x-www-form-urlencoded";. This cannot be overridden.

Here's an example implementation:

Future<Response> post(url, {Map<String, String> headers, body,
    Encoding encoding}) =>
  _withClient((client) => client.post(url,
      headers: headers, body: body, encoding: encoding));

Here's an implementation in real world usage:

  final JsonDecoder _decoder = new JsonDecoder();

  Future<dynamic> post(String url, {Map headers, body, encoding}) {
    return http
        .post(url, body: body, headers: headers, encoding: encoding)
        .then((http.Response response) {
      final String res = response.body;
      final int statusCode = response.statusCode;

      if (statusCode < 200 || statusCode > 400 || json == null) {
        throw new Exception("Error while fetching data");
      }
      return _decoder.convert(res);
    });
  }

Full Example

Let's say you want to fetch data from MongoDB Server and populate a ListView in our flutter application. We'll be making a HTTP GET Request.

(a) pubspec.yaml

dependencies:
  mongo_dart: ^0.3.1
  shelf_rest: any
  http: any
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

(b) main.dart

import 'package:flutter/material.dart';

//import 'package:mongo_dart/mongo_dart.dart' as mongo;
import 'dart:convert';
import 'package:http/http.dart' as http;

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
        // counter didn't reset back to zero; the application is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: new Names(
        pageName: "Facebook Code Test",
      ),
    );
  }
}

class Names extends StatefulWidget {
  final String pageName;

  const Names({Key key, this.pageName}) : super(key: key);

  @override
  _NamesState createState() => _NamesState();
}

class _NamesState extends State<Names> {
  List<Name> _names = new List();
  List<Widget> _namesTiles = new List();
  String uriString =
      "mongodb://DATABASESERVER:27017/rpc1";
  String collectionName = "names";

  @override
  void initState() {
    super.initState();
    _getNames();
  }

  _getNames() async {

    http.Response response = await http.get("http://SERVICEIP:8000/list");
      String body = response.body;
      List data = jsonDecode(body);
      for (Map raw in data) {
        Name name = new Name()
          ..firstName = raw['firstName']
          ..lastName = raw['lastName'];
 //       print("Received $name");
        _names.add(name);
      }
 //   print("received $_names");

    setState(() {
      for (Name found in _names) {
        Text text = new Text("$found");
        _namesTiles.add(text);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: AppBar(
        title: Text(widget.pageName),
      ),
      body: ListView.builder(
        itemBuilder: (context, index) => _namesTiles[index],
        itemCount: _namesTiles.length,
      ),
    );
  }
}

class Name {
  String firstName;
  String lastName;

  @override
  String toString() {
    // TODO: implement toString
    return "$firstName $lastName";
  }
}

Download Full source code here.

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post