For over 5+ years we help companies reach their financial and branding goals. oDesk Software Co., Ltd is a values-driven technology agency dedicated

Gallery

Contacts

Address

108 Tran Dinh Xu, Nguyen Cu Trinh Ward, District 1, Ho Chi Minh City, Vietnam

E-Mail Address

info@odesk.me

Phone

(+84) 28 3636 7951

Hotline

(+84) 76 899 4959

Mobile App oDesk Blog Website Responsive

Moving to Flutter ?

When I started Flutter I was working on a shopping app with Android and iOS native. I start with a course “Learn Flutter & Dart to Build iOS & Android Apps” on Udemy, it’s a great course I watched the first 5 modules and said it’s a very easy language and framework, and start to install it to vscode, add android studio and I found a plugin to android studio “Flutter App Template Generator” it helped me get to structure my project based on redux.

Project structure

The project based on Redux. It like MVI (Model – View – Intent) structure.

Project Packages

The app has the following packages:

  1. data: contains all the data accessing and manipulating components.
  2. features: contains screens and views.
  3. redux: contains store, states, actions, middlewares and reducers.
  4. trans: manage translation in app.
  5. utils: contains utils classes.

Data

Data Package

Data package is responsible for handling the data part of the application.

  • Models
  • Remote repositories
  • Network manager

Models

Pojo classes contain data, have 2 methods fromJson and toJson

fromJson

is named constructor take argument of Map<String, dynamic> to parse json from remote repository response.

dynamic islike Any in kotlin or swift

You can think of named constructor as static function that create object from class (factory pattern)

toJson

is a method used when post the object to remote

Remote repositories

It manages the network API calls and API data handling using Dio.

Dio

Dio is a powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout etc.

Dio is like OkHttp & Retrofit in android or Alamofire in ios

NetworkCommon is singleton class to manage network API calls.

  • Global configuration like base url and timeout.
  • Interceptors for request to put accept-language and content-type and for response to log it or handle response globally.

use NetworkCommon in repositories

Alice

I used alice with dio to inspecting HTTP requests. Alice is an HTTP Inspector tool for Flutter which helps debugging http requests. It catches and stores http requests and responses, which can be viewed via simple UI.

Alice is like Chuck in android

and add this to dio in NetworkCommon
dio.interceptors.add(alice.getDioInterceptor());

Alice

Features

Features Package

It is responsible for laying out the views with specific data on the screen.

ViewModel

MVI Structure

Each screen has view and viewmodel that created from store using redux & flutter_redux

  1. Get store by StoreConnector

According to flutter_rudex StoreConnector is

A descendant Widget that gets the Store from the nearest StoreProvider ancestor, converts the Store into a ViewModel with the given converter function, and passes the ViewModel to a builder function. Any time the Store emits a change event, the Widget will automatically be rebuilt. No need to manage subscriptions!

More details about using Redux in the app will be discussed in the next section.

2. Create viewmodel by static function take store and return viewmodel (factory)

3. Pass viewmodel to view


How to use Redux in your app

Redux is an Application State Management framework. In other words, its main objective is to manage a State.

A nice introduction for Redux https://blog.novoda.com/introduction-to-redux-in-flutter/

Redux one of 3 most commonly used frameworks (BLoC – ScopedModel – Redux), the course teach ScopedModel.

I used redux

  • Redux allows to centralize the management of a State thanks to the fact that Reducers are the only one(s) that can perform the transition from one state to another. This makes the state transition perfectly predictable and thoroughly testable.
  • The ease to insert middlewares in the flow is also an asset. If, for example, you need to constantly validate the connectivity with the server or trace the activities, this is a perfect placeholder for such routines.
  • It forces the developer to structure the application in terms of “Event -> Action -> Model -> ViewModel -> View”.

When to be used ?

  • I could recommend Redux when you need to deal with a global application state, such as, e.g., user authentication, shopping basket, preferences (language, currency)…
  • I would not recommend Redux when you need to handle multiple instances of something, each of them having its own State

To create store you need for three component

  1. App reducers
  2. App state
  3. Middleware (optional)

Actions

Actions are the only types of input accepted by the Store access point. Actions, combined with the current State are used by the Middleware(s) and Reducer to process some function, which could lead to amending the State.

Actions only describe what happened

App reducers

A Reducer is normally a synchronous function which does some processing based on the combination ActionState. The outcome of the processing might lead to a new State.
The Reducer is the only one allowed to change the State.

Middleware

A Middleware is a function commonly aimed at running asynchronously (but not necessarily), based on an Action. A Middleware simply uses a State (or an Action as a trigger) but does not change the State.

It is important to note that, according to Redux recommendations and good practices, there is only one single Store per application. To split the data handling logic, it is advised to use ‘reducer composition’ instead of many stores.

How does it work?

  • When something happens at the UI level (but not limited to the UI, in fact), an Action is created and sent to the Store (via store.dispatch(action));

like in NotificationsViewModel

store.dispatch(GetNotificationsAction(isRefresh: isRefresh));

  • If one or several Middlewares are configured, they are invoked in sequence, passing them the Action and a reference to the Store (so, also the State, indirectly);
  • Middlewares could themselves send an Action to the Store during their processing

next(SyncNotificationsAction(page: page, notifications: list));

  • Then the Action and the current State are also sent to the Reducer
  • The Reducer is the only one that will potentially change the State
  • When the State is changed, the Store notifies all registered listeners to inform them.
  • The UI (but not limited to the UI) can then take appropriate actions linked to change of State.

Debugging redux

I wanted to see my store to ensure every thing is working, So i used flutter_redux_dev_tools with chrome extension Redux DevTools

Redux DevTools like Reactotron in reactnative

make sure to install and run

npm install -g remotedev-server
remotedev --port 8000

Last tip make sure to use function toJson to show store

Data in store showing in remote debug


Bonus

Flutter icon

I used http://fluttericon.com/ to add icons to app. FlutterIcon is a web-based generator of Flutter icon font elements. Customized icon fonts can be produced from not only Material Design Icons, but several popular open source webfonts as well, or by uploading your own svg art.

Conclusions

I think it is an exciting experiment to try. Flutter and Dart have a very cool learning curve and an elegant syntax. Moving from Android or iOS to Flutter is not easy of course, But it deserves a risk. Redux is life saver when things get complicated. And it’s a good choice for many medium to large applications.

Lee Luong – Co Founder & CEO

Author

oDesk Software

Leave a comment