The best way to handle network requests in Flutter

0


 

In my current article known as “Integrating APIs in Flutter” I talked about how we can combine APIs in Flutter. I made use of the well-known HTTP package deal for managing community requests. But it has its personal execs and cons. This article is the extension of my preceding article if you haven’t long gone via it please examine it right here earlier than diving into this article.


In this article as an alternative to the use of the HTTP package, we will use the Dio package deal to cope with our REST API and I will additionally exhibit satisfactory exercise to write a code for community coping within which we are going to create simply one dart type (magic code) that can deal with all HTTP requests (GET, POST, DELETE, PATCH) and that classification file can be used in any kind of undertaking you create in a flutter. But earlier than that what is incorrect with the HTTP package? 

What’s wrong with the HTTP package?

Flutter gives an HTTP bundle that’s first-class whilst performing simple community stuff however when you begin working on a huge utility and we want to do something greater superior task, the HTTP package deal lacks it. Your utility would possibly face a lot of issues with community error handling. In that case, we want some superior library that has some greater performance like interceptors, log, cache, etc. and that’s the place Dio comes in handy. 

What is Dio?

Dio is a powerful HTTP client for dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout, etc. By comparing the HTTP package with Dio, Dio provides an intuitive API for performing advanced network tasks with minimal effort. 

Getting started


If you prefer the ultimate code simply alternate the department from grasp to dio. Let’s add dio to our project. Go to pubsec.yaml, underneath the dependencies, add the dio package. 

dependencies:
  dio:

Run “flutter pub get” to deploy the package. Now, head over to the offerings folder in which we already have one file referred to as http_service.dart. Let’s make modifications to this file. 

The Magic Code


import 'dart:io';

import 'package:dio/dio.dart';

enum Method { POST, GET, PUT, DELETE, PATCH }

const BASE_URL = "https://fakestoreapi.com/";

class HttpService {
  Dio? _dio;

  static header() => {"Content-Type": "application/json"};

  Future<HttpService> init() async {
    _dio = Dio(BaseOptions(baseUrl: BASE_URL, headers: header()));
    initInterceptors();
    return this;
  }

  void initInterceptors() {
    _dio!.interceptors.add(
      InterceptorsWrapper(
        onRequest: (requestOptions, handler) {
          logger.i(
              "REQUEST[${requestOptions.method}] => PATH: ${requestOptions.path}"
              "=> REQUEST VALUES: ${requestOptions.queryParameters} => HEADERS: ${requestOptions.headers}");
          return handler.next(requestOptions);
        },
        onResponse: (response, handler) {
          logger
              .i("RESPONSE[${response.statusCode}] => DATA: ${response.data}");
          return handler.next(response);
        },
        onError: (err, handler) {
          logger.i("Error[${err.response?.statusCode}]");
          return handler.next(err);
        },
      ),
    );
  }

  Future<dynamic> request(
      {required String url,
      required Method method,
      Map<String, dynamic>? params}) async {
    Response response;

    try {
      if (method == Method.POST) {
        response = await _dio!.post(url, data: params);
      } else if (method == Method.DELETE) {
        response = await _dio!.delete(url);
      } else if (method == Method.PATCH) {
        response = await _dio!.patch(url);
      } else {
        response = await _dio!.get(url, queryParameters: params);
      }

      if (response.statusCode == 200) {
        return response;
      } else if (response.statusCode == 401) {
        throw Exception("Unauthorized");
      } else if (response.statusCode == 500) {
        throw Exception("Server Error");
      } else {
        throw Exception("Something does wen't wrong");
      }
    } on SocketException catch (e) {
      logger.e(e);
      throw Exception("Not Internet Connection");
    } on FormatException catch (e) {
      logger.e(e);
      throw Exception("Bad response format");
    } on DioError catch (e) {
      logger.e(e);
      throw Exception(e);
    } catch (e) {
      logger.e(e);
      throw Exception("Something wen't wrong");
    }
  }
}

Delete the total code which is written in our http_service.dart file and add the above code. Let me give an explanation of you the code one via one. We have declared an enum referred to as Method which holds all HTTP Methods (line no. 5). Inside the HttpService category we have a static technique known as header() which has a configuration of a Content-Type. You can additionally add an authorization header to this approach whilst dealing with authorization. Inside the init() method, we initialized our Dio occasion with BaseOpotions which accepts the base URL and it has a non-compulsory parameter known as a header. We bypass our earlier written technique header() to it (this is also referred to as a function/method as a parameter). We additionally have interceptors that assist us to log our requests, response, and error. I will go tons deeper into the standards of interceptors in different articles however this is an excellent article to apprehend what Interceptors are. The important vital phase to think about right here is our request() technique due to the fact that’s the place all the magic happens. It accepts two required parameters and one elective parameter referred to as URL, method, and params respectively. The code is self-explanatory, we test the kind of technique and do the requests accordingly. We have additionally wrapped our code inner a try-catch block for error dealing with which throws exceptions in accordance to the fame code we received. On line range seventy-four we have DioError which is a type that helps to manage Dio errors.

Yeah! That’s it we are performed with our magic code. You can take this code in any flutter mission and deal with any kind of HTTP request. 

Making changes in our project


While writing the above HttpService type you will come upon the mistakes in the product_controller.dart file too. Let’s make modifications in this file too to make our app running. 

import 'package:get/get.dart';
import 'package:shopme/src/constants/app_constants.dart';
import 'package:shopme/src/models/product_models.dart';
import 'package:shopme/src/services/http_service.dart';
import 'package:dio/dio.dart' as d;

class ProductController extends GetxController {
  var isLoading = true.obs;
  var productList = [].obs;
  HttpService httpService = HttpService();

  @override
  void onInit() {
    httpService.init();
    fetchProducts();
    super.onInit();
  }

  void fetchProducts() async {
    try {
      isLoading(true);
      final result =
          await httpService.request(url: "products", method: Method.GET);
      if (result != null) {
        if (result is d.Response) {
          var products = List<ProductsModel>.from(
              (result.data).map((x) => ProductsModel.fromJson(x)));
          productList.value = products;
          logger.d(products);
        } else {
          isLoading(false);
        }
      }
    } finally {
      isLoading(false);
    }
  }
}


Instantiate HttpService type (line no. 10). The solely trade we have to make in this file is in fetchProducts() method. Pass the required parameter i.e. url and method. As we have already cited the base URL in our HttpService class, right here we simply have to add the route which we have to hit. For example, right here we have hit the “products” route. Pass “products” to url parameter. We are making a GET request so omit Method.GET to a technique parameter (line no. 23–24). Check the end result is null or no longer additionally test if the response we get is of Dio response. Finally, we replace our product listing (line no. 24–30). 

Final output




Post a Comment

0Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Accept !