Beamer v1.0.0 is out! What’s new and how to migrate

Sandro Lovnički
Flutter Community
Published in
5 min readDec 4, 2021

After being on pub.dev for almost a year, tested and used by many individuals and companies, the long-awaited v1.0.0 is finally released.

Table of Contents

Introduction

Beamer is a routing package for all platforms that lets you navigate through guarded page stacks and URLs using the Router and Navigator’s Pages API, aka “Navigator 2.0”.

If you are unfamiliar with these navigation concepts, Learning Flutter’s new navigation and routing system is a great article to start with. The rest of this article assumes familiarity with said concepts and some familiarity with Beamer whose README can be read in the link below.

There are 2 main ideas that guided Beamer’s inception:

  • Make the use of Router API easier, especially for beginners
  • Segregate the responsibility of creating a page stack, for intermediate and advanced usage

First point is solved by having default implementations for RouterDelegate and RouteInformationParser , i.e. BeamerDelegate and BeamerParser . Both can take various parameters for customization. Having named routes showed to be a desired feature at the very beginning, so there is a RoutesLocationBuilder that can be configured with a familiar routes Map. After the setup, navigation can be done via something like Beamer.of(context).beamToNamed('/my/page/2') which made the transition from Navigator.of(context).pushNamed('/my-page') very natural for newcomers.

Second point is accomplished by the concept of a BeamLocation that is responsible for deciding, based on its state, which pages should BeamerDelegate put into Navigator.pages when (re)building it. The idea here is to define a different BeamLocation for a different “area/location/world” inside the app. For example, we can have BooksBeamLocation that will handle all combination of books-related pages in a stack and an ArticlesBeamLocation that will handle all article-related pages in a stack. Benefits of this approach can be seen very soon when having to build an application containing 10+ screens organized in a couple of “contextually different” page stacks.

When defining your BeamLocation , the state used for it can be either the default BeamState (that holds various route parameters important for decisions on how to build a page stack) or a completely custom state object, even (but not necessary) a ChangeNotifier . When using a custom ChangeNotifier for the state of BeamLocation , one can accomplish pure declarative navigation. Still, even with ChangeNotifier state, one is able to navigate imperatively just the same. Beamer does not prefer one over the other and handles both similarly under the hood. The next goal may be to make the default BeamState be a ChangeNotifier , but that’s a topic for the next article :)

The flow of what happens after each navigation action can be seen in the diagram below:

What’s new after v0.14.1

A complete CHANGELOG can be seen here at pub.dev, so we’ll go over the reasons behind each breaking change and some notable mentions.

Changes on BeamState

  1. It is now mixed with RouteInformationSerializable, a mixin defined in Beamer that every state for BeamLocation must mix with
  2. pathBlueprintSegments is renamed to pathPatternSegments

Changes on BeamerDelegate

  1. Some of you may notice, especially if using Beamer.of(context).update directly, that BeamerDelegate also stores its “state”. This was a BeamState called state until now, but that didn’t feel quite right. Now this is a RouteInformation called configuration to be named the same as it’s in RouterDelegate
  2. All of the beaming parameters such as transitionDelegate, beamBackOnPop and others have been extracted into a BeamParameters object. This is not a breaking change as these parameters stayed the same in beaming functions, but is a change that, together with above change, influenced following changes
  3. The locationBuilder now takes RouteInformation and BeamParameters instead of BeamState. This is a natural consequence of above changes, but also an improvement because it provides an ability to save BeamParameters into history, something that was not possible before
  4. beamStateHistory and beamLocationHistory have been replaced with beamingHistory that is a List<BeamLocation> and each BeamLocation has history that is List<HistoryElement> where HistoryElement holds RouteInformation and BeamParameters. That sentence escalated quickly, but now we have a very stable and well-structured beaming history
  5. listener is renamed to routeListener and a new buildListener is added. This way we can listen both on incoming routes (before build) and at build (where we also have access to pages)

Changes on BeamLocation

  1. Because of the changes on BeamerDelegate, the constructor now takes optional RouteInformation and BeamParameters
  2. A type T for state now must mix with RouteInformationSerializable and a generic type for state must be specified when extending the BeamLocation, even when using the default BeamState
  3. pathBlueprints is renamed to pathPatterns and is a List<Pattern>

Changes on SimpleLocationBuilder

  1. Renamed to RoutesLocationBuilder. This was due to discussions at Navigator 2.0 API Usability Research
  2. The values of routes now also receive the Object? data parameter.

Changes on BeamPage

  1. pageRouteBuilder is replaced with more generic routeBuilder
  2. We have a const constructor now
  3. A static routePop is added that can be used instead of default pathSegmentPop for onPopPage

Changes on BeamGuard

  1. pathBlueprints renamed to pathPatterns
  2. beamTo and beamToNamed now also receive origin and target which are BeamLocations of where it’s being beamed from and where it’s being beamed to (which was guarded)

Additions to examples

How to migrate

Although there have been a lot of changes, migration is pretty straightforward. We’ll go through 2 migrating scenarios; when using the SimpleLocationBuilder and when using a custom BeamLocation.

SimpleLocationBuilder

As we mentioned above, SimpleLocationBuilder was renamed to RoutesLocationBuilder. That’s 50% of migration done and we only need to add data parameter to the routes, but let’s write some code.

Previously we had something like this

After the migration, we should have something like this

Custom BeamLocation

As mentioned, we’ll have to rename pathBlueprints to pathPatterns and put a concrete state type when extending BeamLocation.

On v0.14.1 we could have

Now we have

Note how we can now use const constructor of BeamPage instead of needing to use it on all properties (if we develop with prefer_const_constructors linter rule).

Miscellaneous

Accessing currentBeamLocation.state
Now the state type cannot be automatically inferred (even if it’s a default BeamState) so we need to cast it manually to be able to access desired attributes of its type.

Before we could do

Now we must

BeamGuard
As in BeamLocation, pathBlueprints is renamed to pathPatterns and beamTo/ beamToNamed got 2 parameters.

Before we had

Now we have it like this

Final thoughts

I hope this article was helpful to anyone already using Beamer or even to someone thinking of starting the journey towards new navigation concepts. It sure was (and is) fun for me and I plan to write some more about it in the future.

Feel free to visit Beamer’s GitHub repository or Discord server for further discussions and questions you may have.

--

--

Sandro Lovnički
Flutter Community

Fluttering @FFireEsports 🔥 Maintaining Beamer 💻 Hosting Flutter dArtists 📢 Organizing @FlutterCroatia , @gdgzagreb 🇭🇷 Loving Petra and our cat ❤️