Flutter Navigator Middleware Part 2 — Middleware Service Class

Payam Zahedi
Flutter Community
Published in
4 min readJun 26, 2020

Intro

in the 1st part, we learned about how to use the RouteObserver class and we created a simple example to see how it will work. as we mentioned earlier :

RouteObserver class is used when we want to observe over navigator changes(like Navigator Pop or Push). If you want to be aware of navigator changes you should implement RouteAware as a mixin for your single widget(Screen).

in this part, we will create a service class that is aware of every change that will happen in Navigator Widget (Pop, Push, Replace, and …). this class will be very useful in many use cases. if you are familiar with RouteObserver class keep reading. otherwise, I recommend you to first read the 1st part.

in this part we will learn:

  1. what is the NavigatorObserver and its relationship with Navigator?
  2. create navigator middleware class
  3. log all navigator changes
  4. create a stack for navigator
  5. create callbacks for our middleware class

for complete source code checkout this link.

What is the relationship between RouteObserver with Navigator widget?

If you check the RouteObserver class code, you will see that it is extended from NavigatorObserver abstract class.

NavigatorObserver is:

An interface for observing the behavior of a Navigator.

and if you look at NavigatorObserver class code, you will see something like this.

NavigatorObserver

now you know that RouteObserver is a NavigatorObsererver with some more functionality. let's find out the relation of these two classes with Navigator class. if you look at Navigator constructor you will see it has an observer property that will take a List of NavigatorObserver.

Navigator widget uses this property to notify all observers about changes. for example when we use:

Navigator.push(context, nextRoute)

Navigator will navigate to next Route and it will notify all observers and tell them “hey guys we have a push event”. the following code shows how Navigator notify its observers.

so in this section, We find out that RouteObserver is a NavigatorObserever and Navigator class has a list of observers as a property. and it will use this theme to notify it’s observers whenever it has changed states like push, pop, replace, and …

Now we know how Navigator widget and NavigatorObserver work. and it’s time to create our magical NavigatorMiddleware class.

Navigator Middleware class

we can create our middleware class with extends it from NavigatorObserver or RouteObserver. Because RouteObserver class has more capabilities, let’s use it. first of all, we need to create a file in our project and named it to something like navigator_middleware.dart. inside it, we should create NavigatorMiddleware class and extends it from RouteObserver class. we will override did* (didPus, didPop, …) methods first. the initial code will be something like this:

We have already built our middle class. now let’s make a logger for it. this logger will log every time the navigator will invoke did* methods of our middleware class. so we will update our code to this:

let’s play more with it. it's very useful if we have a navigator stack. the stack is simply a list of navigator routes. that’s great, isn’t it?

we should create the List<R> property and update it in all did* methods. we also want to log stack changes. look at below code:

we create a stack for our middleware class. now we can find thatwhat route we have in our application. imagine you want to navigate pop to X page if it exists in navigator stack. we can simply check if our stack contains the X page then pop to it.

and for last magic, we can create some callbacks for each did* methods. and invoke them in the related method. this will very useful when we want to do something from outside of middleware class. for example, if the incoming route is Y route we should have an API call. so first we will create a typedef for our call back.

typedef OnRouteChange<R extends Route<dynamic>> = void Function(R route, R previousRoute);

final code will be like this:

We finished working with our NavigatorMiddleware class. it’s time to use it in our main.dart and MaterialApp. let’s include it in our app. we will update our main.dart file to this:

run the app and check the console. tadaaaaa

Conclusion

We talk about NavigationObserver, RouteObserver, and Navigator widget classes and their relationships. after that, we create our NavigatorMiddleware class that can help us in various scenarios. we also create a stack and logger for our class and in the end create a callback for each method of our class.

https://www.twitter.com/FlutterComm

--

--

Payam Zahedi
Flutter Community

I’m a Software Engineer, Flutter Developer, Speaker & Open Source Lover. find me in PayamZahedi.com