Flutter queue API requests to execute later

3.9k views Asked by At

I am implementing an app that I should handle offline mode. When I check the internet connection and it is not connected, I should add the API request to a queue to be executed when the internet connection is back again.

How can I do that?

I tried to add class names and the method names to the queue, but couldn't call the method from a class dynamically.

I am using Dio package to handle API requests.

2

There are 2 answers

0
Sajjad On

if you remove await from your requests you can save them as Future<dynamic> for Example

Future<dynamic> response = Dio().get("http://www.google.com");

now You can save it in List<Future<dynamic>> myList = List() and when you want to call it

await myList[0]

Or

myList[0].then()

0
Rakesh Lanjewar On

I have Implemented in this way. I know it too late to answer the question but still it will be useful in future.

FailedOrderQueue.dart

import 'dart:convert';

import 'package:get_storage/get_storage.dart';
import 'package:select_driver_app/Models/Order.dart';

class FailedOrdersQueue {
  GetStorage box = new GetStorage();
  List items = [];

  bool get hasItems {
    return items.isNotEmpty;
  }

  bool get isEmpty {
    return items.length == 0;
  }

  FailedOrdersQueue() {
    // removeAll();
    items = _loadQueue();
  }

  List _loadQueue() {
    return box.read('queue') ?? [];
  }

  bool exists(int orderId) {
    if (items.isEmpty) {
      return false;
    }
    try {
      dynamic object = items.firstWhere(
        (element) => element['order_id'] == orderId,
      );

      return object == null ? false : true;
    } catch (e) {
      return false;
    }
  }

  removeAll() {
    items = [];
    _commit();
  }

  add(Order order, int currentTripId) {
    if (!exists(order.id)) {
      items.add({
        'order_id': order.id,
        'trip_id': currentTripId,
        'credit_note': jsonEncode(order.creditNoteList),
        'delivery_img_path': order.image,
        'sign_img_path': order.signature
      });

      _commit();
    }
  }

  _commit() {
    box.write('queue', items);
  }

  remove(Order order) {
    items.removeWhere(
      (element) => element['order_id'] == order.id,
    );
    _commit();
  }

  removeById(int id) {
    items.removeWhere(
      (element) => element['order_id'] == id,
    );
    _commit();
  }
}

main.dart or in controller(Getx)

FailedOrdersQueue failedOrderQueue = new FailedOrdersQueue();

failedOrderQueue.add(order, currentTripId!);
failedOrderQueue.remove(order);

failedOrderQueue.items.forEach((rawOrderInfo) {
   //process the queue
});

This approach save the data in the Get storage, if you don't want to persist data then you can remove it.