Beamer v1.0.0 is out! What’s new and how to migrate
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
- It is now mixed with
RouteInformationSerializable
, a mixin defined in Beamer that every state forBeamLocation
must mix with pathBlueprintSegments
is renamed topathPatternSegments
Changes on BeamerDelegate
- Some of you may notice, especially if using
Beamer.of(context).update
directly, thatBeamerDelegate
also stores its “state”. This was aBeamState
calledstate
until now, but that didn’t feel quite right. Now this is aRouteInformation
calledconfiguration
to be named the same as it’s inRouterDelegate
- All of the beaming parameters such as
transitionDelegate
,beamBackOnPop
and others have been extracted into aBeamParameters
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 - The
locationBuilder
now takesRouteInformation
andBeamParameters
instead ofBeamState
. This is a natural consequence of above changes, but also an improvement because it provides an ability to saveBeamParameters
into history, something that was not possible before beamStateHistory
andbeamLocationHistory
have been replaced withbeamingHistory
that is aList<BeamLocation>
and eachBeamLocation
hashistory
that isList<HistoryElement>
whereHistoryElement
holdsRouteInformation
andBeamParameters
. That sentence escalated quickly, but now we have a very stable and well-structured beaming historylistener
is renamed torouteListener
and a newbuildListener
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
- Because of the changes on
BeamerDelegate
, the constructor now takes optionalRouteInformation
andBeamParameters
- A type
T
forstate
now must mix withRouteInformationSerializable
and a generic type for state must be specified when extending theBeamLocation
, even when using the defaultBeamState
pathBlueprints
is renamed topathPatterns
and is aList<Pattern>
Changes on SimpleLocationBuilder
- Renamed to
RoutesLocationBuilder
. This was due to discussions at Navigator 2.0 API Usability Research - The values of
routes
now also receive theObject? data
parameter.
Changes on BeamPage
pageRouteBuilder
is replaced with more genericrouteBuilder
- We have a
const
constructor now - A static
routePop
is added that can be used instead of defaultpathSegmentPop
foronPopPage
Changes on BeamGuard
pathBlueprints
renamed topathPatterns
beamTo
andbeamToNamed
now also receiveorigin
andtarget
which areBeamLocation
s 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.