This article by Jian Yue SimpRead transcoding, original address medium.com

Running for almost a year on pub.dev, tested and used by many individuals and companies, long……

Beamer V1.0.0 has been released! What is new and how to migrate

After running on pub.dev for almost a year, and after testing and use by many individuals and companies, the long-awaited _v1.0.0_ has finally been released.

directory

  • Introduction to the
  • What’s new after V0.14.1
  • How to transfer
  • Final thoughts

Introduction to the

Beamer is an all-platform routing package that lets you navigate through protected page stacks and urls using Router and Navigator’s Pages API (aka “Navigator 2.0”).

Learning Flutter’s new Navigation and Routing System is a good article to start reading if you are not familiar with these navigation concepts. The rest of this article assumes familiarity with the above concepts and some familiarity with Beamer, whose README can be read at the link below.

Beamer | Flutter package

Handle routing of your application on all platforms, synchronizing it with the browser URL bar, and so on. The power Beamer uses is…

Pub. Dev/packages/be…

Two main ideas guided Beamer’s birth.

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

The first is addressed through the default implementation of “RouterDelegate “and “RouteInformationParser”, namely “BeamerDelegate “and “BeamerParser”. Both can be customized by taking various parameters. Having named routes appears to be a desired feature from the start, so there is a RoutesLocationBuilder that can be configured with the familiar Routes map. Once set, navigation can be done by beaming.of (context).beamtonamed (‘/my/page/2’), This makes the transition from navigator.of (context).pushnamed (‘/my-page’) very natural for newcomers.

The second is accomplished by the concept of a BeamLocation, which is responsible for determining, based on its state, which pages the BeamerDelegate should put into navigator.pages when it (re) builds. The idea here is to define different BeamLocations for different “regions/places/worlds” in the application. For example, we could have BooksBeamLocation to handle all combinations of book-related pages in a stack, and ArticlesBeamLocation to handle all articles-related pages in a stack. The benefits of this approach quickly become apparent when you need to build an application with more than 10 screens organized into several “context-different” page stacks.

When defining your “BeamLocation “, the “state “used for it can be either the default “BeamState” (which holds various routing parameters important in deciding how to build a page stack) or a completely custom state object, Even (but not required) a “ChangeNotifier”. Pure declarative navigation can be achieved when a custom ChangeNotifier is used as the state of a BeamLocation. However, even with the ChangeNotifier state, people can perform mandatory navigation just as well. Mr Beamer does not favour one over the other; his treatment of both is similar. The next goal might be to make the default BeamState a ChangeNotifier, but that’s the subject of the next article 🙂

The flow that occurs after each navigation action can be seen in the figure below.

What’s new after V0.14.1

A full change log can be seen at pub.dev, so we’ll take a look at the reasons behind each breakthrough change and some points worth mentioning.

The change of BeamState

  1. It is withRouteInformationSerializableBlend, which is a blend element defined in Beamer, eachBeamLocationMust be mixed with it.
  2. pathBlueprintSegmentsrenamedpathPatternSegments.

The change of BeamerDelegate

  1. Some of you may have noticed, especially if used directlyBeamer.of(context).update.BeamerDelegateIt also stores its “state”. Before that, this was a program calledThe state of 'BeamState’, but that doesn’t feel right. Now this is a “Configuration”RouteInformation, andRouterDelegateWith the same name.
  2. All beam parameters such astransitionDelegate', BeamBackOnPop ‘and others are extracted into a’ BeamParameters’ object. This is not a breakthrough change, as these parameters remain unchanged in the beam function, but it is a change that, along with the above changes, affects the following changes
  3. locationBuilderNow acceptRouteInformationandBeamParametersRather thanBeamState. This is a natural consequence of the above changes, but also an improvement as it provides willBeam parametersThe ability to preserve history in a way that wasn’t possible before.
  4. beamStateHistoryandbeamLocationHistoryBe replaced bybeamingHistoryIt’s aList<BeamLocation>, eachBeamLocationThere arehistory, it isList<HistoryElement>, includingHistoryElementholdRouteInformationandBeamParameters. That phrase quickly escalated, but now we have a very stable and well-structured beam history.
  5. listenerHas been renamed torouteListenerAnd added a new onebuildListener. This way, we can listen for incoming routes (before build) and at build time (where we can also access the page).

The change of BeamLocation

  1. Due to the “BeamerDelegate “change, the constructor now requires optional” routing information “and “BeamParameters”.
  2. “State” of the “T” type must be mixed with “RouteInformationSerializable”, now in the extension “BeamLocation”, must specify a generic types for state, even use the default “BeamState”.
  3. PathBlueprints' namePathPatterns’, is oneList<Pattern>.

Changes about SimpleLocationBuilder

  1. renameRoutesLocationBuilder. This is due toNavigator 2.0 API Usability ResearchThe discussion of the
  2. routesThe value of is now also acceptedObject? dataParameters.

Changes on BeamPage

  1. pageRouteBuilderBe more versatilerouteBuilderTo be replaced.
  2. We now have oneconstThe constructor
  3. Added a static oneRoutePop ', can be used instead of the defaultPathSegmentPop ‘for’ onPopPage’.

The change of BeamGuard

  1. pathBlueprintsrenamedpathPatterns.
    1. beamToandbeamToNamedNow also receiveoriginandtargetThey are the place to which they are transmitted and the place to which they are transmittedBeamLocation(This is protected).

A supplement to the example

  • Guard riverpod example
  • Firebase core instance
  • Firebase auth example
  • ChangeNotifier Custom status example

How to transfer

Although there are many changes, migration is very straightforward. We will go through two migration schemes; When using SimpleLocationBuilder and using custom BeamLocation.

Simple locator generator

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

We used to have something like this

final routerDelegate = BeamerDelegate(
  locationBuilder: SimpleLocationBuilder(
    routes: {
      '/': (context, state) => MyWidget(),
      '/another': (context, state) => MyAnotherWidget(),
    },
  ),
  // other properties...
);
Copy the code

After migration, we should have something like this

final routerDelegate = BeamerDelegate(
  locationBuilder: RoutesLocationBuilder(
    routes: {
      '/': (context, state, data) => MyWidget(),
      '/another': (context, state, data) => MyAnotherWidget(),
    },
  ),
  // other properties...
);
Copy the code

Custom BeamLocation

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

In version 0.14.1, we can have

class BooksLocation extends BeamLocation {
  @override
  List<Pattern> get pathBlueprints => ['/'.'/books'];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) {
    return [
      BeamPage(
        key: const ValueKey('home'),
        child: const HomeScreen(),
      ),
      if (state.uri.pathSegments.contains('books'))
        BeamPage(
          key: const ValueKey('books'),
          child: constBooksScreen(), ), ]; }}Copy the code

Now we have

class BooksLocation extends BeamLocation<BeamState> {
  @override
  List<Pattern> get pathPatterns => ['/'.'/books'];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) {
    return [
      const BeamPage(
        key: ValueKey('home'),
        child: HomeScreen(),
      ),
      if (state.uri.pathSegments.contains('books'))
        const BeamPage(
          key: ValueKey('books'), child: BooksScreen(), ), ]; }}Copy the code

Note that we can now use the BeamPage of the const constructor instead of using it on all attributes (if we develop with the prefer_const_constructors lint rule).

miscellaneous

Visit currentBeamLocation. State

Now, the state type cannot be inferred automatically (even if it is a default BeamState), so we need to cast it manually to be able to access the required properties of its type.

We could have done it before

final beamState = Beamer.of(context).currentBeamLocation.state;
final bookId = beamState.pathParameters['bookId'];
Copy the code

Now we have to

final beamState = Beamer.of(context).currentBeamLocation.state as BeamState;
final bookId = beamState.pathParameters['bookId'];
Copy the code

BeamGuard

For example, in BeamLocation, pathBlueprints are renamed pathPatterns, and beamTo/beamToNamed gets two parameters.

We used to have

BeamGuard(
  pathBlueprints: ['/login'],
  guardNonMatching: true,
  check: (context, location) => context.isUserAuthenticated(),
  beamToNamed: '/login'.)Copy the code

Now we have parameters like this

BeamGuard(
  pathPatterns: ['/login'],
  guardNonMatching: true,
  check: (context, location) => context.isUserAuthenticated(),
  beamToNamed: (origin, target) => '/login'.)Copy the code

Final thoughts

I hope this article will be helpful to anyone who is already using Beamer, or even to anyone who is considering starting a new navigation concept. It was definitely (and was) fun for me, and I plan to write more about it in the future.

Feel free to visit Beamer’s GitHub repository or Discord server to further discuss and understand any problems you may be encountering.


www.deepl.com translation