Flutter Redux – Part 3 Async

This continuation of previous two blogs on redux flutter. In this we explore more redux tools like how to perform async operations and dev tools.

Middleware

Till now we haven’t seen any async flow in redux. Rather redux principle’s don’t support async flow at all. We need to introduce middleware for this purpose.

Middleware is just simply a piece of code which executes when a action is called. The only difference it doesn’t have to follow redux principles strictly?

To see how to implement a middleware let’s see an example

class LogMiddleware implements MiddlewareClass<AppState> {
  @override
  void call(Store<AppState> store, dynamic action, NextDispatcher next) {
    print("===MIDDLEWARE===");
    print(action);
    next(action);  //very important :)
  }
}

So as you can we implement “MiddlewareClass” and override the call function. In your store add your middleware

final store = Store<AppState>(appReducer,
    initialState: AppState.fromList(List.from(["Item1", "Item2"])),
    middleware: [
      LogMiddleware()
    ]
    );

Now what this does is just simply log all actions which are called !! As simple as that.

https://github.com/excellencetechnologies/flutter_redux_demo/commit/59b3ca48a93799a2e1546adbfd6dde1602fb93b3

Next let’s look at async action. Let’s populate our list . Before doing this we need to create a service, model etc which we seen in previous blogs. So i will just put in the code for it.

//services/fetch_list.dart

import 'package:flutter_redux_demo/models/item.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:math';


class PostService {
  static Future<Item> fetchRandomPost() async {
    var rng = new Random();
    var postID = rng.nextInt(100);
    final response =
        await http.get('https://jsonplaceholder.typicode.com/posts/$postID');

    if (response.statusCode == 200) {
      // If server returns an OK response, parse the JSON.
      return Item.fromJson(json.decode(response.body));
    } else {
      // If that response was not OK, throw an error.
      throw Exception('Failed to load post');
    }
  }
} 

Next, define out action

class FetchItemAction{
  FetchItemAction();
}

Next, this is our middleware

import 'package:flutter_redux_demo/models/item.dart';
import 'package:flutter_redux_demo/redux/actions.dart';
import 'package:flutter_redux_demo/redux/app_state.dart';
import 'package:flutter_redux_demo/service/fetch_list.dart';
import 'package:redux/redux.dart';

class FetchListMiddleware implements MiddlewareClass<AppState> {
  @override
  void call(Store<AppState> store, dynamic action, NextDispatcher next) {
    if (action is FetchItemAction) {
      () async {
        // store.dispatch(ShowApploading()) we can do something like this as well.
        try {
          Item item = await PostService.fetchRandomPost();
          print("fetched item $item");
          store.dispatch(AddItemAction(item));
        } catch (e) {
          print(e);
          //store.dispatch(.. some exception handling ...)
        }
      }();
    }
    next(action); // very important :)
  }
}

most things are self explanatory.

Next, add a button to fetch call this action, i would be using the FloatingActoinButton

class FetchButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, VoidCallback>(converter: (store) {
      return () => store.dispatch(FetchItemAction());
    }, builder: (context, cb) {
      return FloatingActionButton(
        onPressed: () {
          cb();
        },
        child: Icon(Icons.refresh),
      );
    });
  }
}

All done! See full source here https://github.com/excellencetechnologies/flutter_redux_demo/commit/59b3ca48a93799a2e1546adbfd6dde1602fb93b3

Cool! We have setup async calls as well with redux.

At this stage, all basics of Redux Flutter should be fully clear and we can start to develop our original app now again! 🙂

Also few important things before we miss them.

https://pub.dev/packages/flutter_redux_dev_tools

This is a very useful dev tool to debug redux calls. This supports something called as time travel . This is quite useful, and ideally should be used during development in most cases.

Also you can look at this middleware https://github.com/Cretezy/redux_persist to persist data 🙂

excellence-social-linkdin
excellence-social-facebook
excellence-social-instagram
excellence-social-skype