Generates reusable chunks of serializable properties that can be assigned to containing classes.

Here are a couple of scenarios where this might be useful:

  • A collection of subclasses that share a large number of properties, like FormField widgets, where you want to pass these properties to the constructor, but don't want to have to write all the boilerplate code;
  • A typed routing system, where the route's arguments are also parameters to the widget that's eventually built from them.

Start with the base class

import 'package:flutter_degen/annotations.dart';

/// Doesn't have to be abstract
abstract class PersonPageParams {
  final String personId;
  final Person person;
  final bool showHistory;
  
  PersonPageParams({
    @required this.personId, 
    this.person, 
    this.showHistory = false});
}

Create a "subclass"

In the target class, you need to:

  • Add part '{file_name}.g.dart'
  • Create a @delegate property
  • Apply a mixin using the naming convention _{baseClassName}Mixin

part 'person_route_args.g.dart';

/// Route arguments
class PersonRouteArgs extends RouteArgs with _PersonPageParamsMixin {
  
  /// Here is the delegate property
  @delegate(implementDelegate=true)
  final PersonPageParams _params;

  /// This example has another property, for illustration purposes 
  @override
  final uriTemplate = "/person/{personId}";
  
  /// The primary constructor.  This constructor requires an instance of PersonPageParams.
  PersonRouteArgs(this._params);

  /// A flattened constructor.  The args from PersonPageParams will be flattened.  See the `fromUri` 
  /// constructor below 
  PersonRouteArgs.of(@flatten() this._params);
  
  
  /// For illustration purposes, a factory constructor could exist
  factory PersonRouteArgs.fromUri(args) {
    return PersonRouteArgs.of(personId: args["personId"]);
  }
}

Now we can create another subclass

This time we'll create a widget that takes in the same arguments

/// Person widget
class PersonPage extends StatefulWidget with _PersonPageParamsMixin {
  
  @delegate(implementDelegate=true)
  final PersonPageParams _params;

  PersonPage.ofArgs(this._params, {Key key}): super(key: key);
  
  /// This will flatten out delegate's constructor
  PersonPage(@flatten() this._params, {Key key}): super(key: key);
  
  ... 
}

Run the generator

# flutter pub run build_runner build

Libraries

annotations
build
flutter_degen