Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/go_router_builder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.3.0

- Adds support for custom types through `TypedQueryParameter` annotation. The `encoder`, `decoder` and `compare` parameters allow specifying custom functions for encoding, decoding and comparing query parameters in `TypedGoRoute` constructors. For example, you can use a `DateTime` parameter with a custom encoder and decoder to convert it to and from a string representation in the URL.

## 4.2.1

* Adds support for analyzer 11 and 12.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,29 @@ part 'typed_query_parameter_example.g.dart';

void main() => runApp(App());

class CustomParameter {
const CustomParameter({required this.valueString, required this.valueInt});

final String valueString;
final int valueInt;

static String encode(CustomParameter parameter) {
return '${parameter.valueString},${parameter.valueInt}';
}

static CustomParameter decode(String value) {
final List<String> parts = value.split(',');
return CustomParameter(
valueString: parts[0],
valueInt: int.parse(parts[1]),
);
}

static bool compare(CustomParameter a, CustomParameter b) {
return a.valueString != b.valueString || a.valueInt != b.valueInt;
}
}

class App extends StatelessWidget {
App({super.key});

Expand All @@ -31,30 +54,52 @@ class IntRoute extends GoRouteData with $IntRoute {
@TypedQueryParameter(name: 'int_field_with_default_value')
this.intFieldWithDefaultValue = 1,
@TypedQueryParameter(name: 'int field') this.intFieldWithSpace,
@TypedQueryParameter<CustomParameter>(
encoder: CustomParameter.encode,
decoder: CustomParameter.decode,
)
this.customField,
@TypedQueryParameter<CustomParameter>(
encoder: CustomParameter.encode,
decoder: CustomParameter.decode,
compare: CustomParameter.compare,
)
this.customFieldWithDefaultValue = const CustomParameter(
valueString: 'default',
valueInt: 0,
),
});

final int? intField;
final int intFieldWithDefaultValue;
final int? intFieldWithSpace;
final CustomParameter? customField;
final CustomParameter customFieldWithDefaultValue;
@override
Widget build(BuildContext context, GoRouterState state) => Screen(
intField: intField,
intFieldWithDefaultValue: intFieldWithDefaultValue,
intFieldWithSpace: intFieldWithSpace,
customField: customField,
customFieldWithDefaultValue: customFieldWithDefaultValue,
);
}

class Screen extends StatelessWidget {
const Screen({
super.key,
required this.intField,
required this.intFieldWithDefaultValue,
this.intFieldWithSpace,
super.key,
this.customField,
required this.customFieldWithDefaultValue,
});

final int? intField;
final int intFieldWithDefaultValue;
final int? intFieldWithSpace;
final CustomParameter? customField;
final CustomParameter customFieldWithDefaultValue;

@override
Widget build(BuildContext context) => Scaffold(
Expand All @@ -75,6 +120,8 @@ class Screen extends StatelessWidget {
intField: newValue,
intFieldWithDefaultValue: intFieldWithDefaultValue,
intFieldWithSpace: intFieldWithSpace,
customField: customField,
customFieldWithDefaultValue: customFieldWithDefaultValue,
).go(context);
},
),
Expand All @@ -88,6 +135,8 @@ class Screen extends StatelessWidget {
intField: intField,
intFieldWithDefaultValue: newValue,
intFieldWithSpace: intFieldWithSpace,
customField: customField,
customFieldWithDefaultValue: customFieldWithDefaultValue,
).go(context);
},
),
Expand All @@ -101,6 +150,46 @@ class Screen extends StatelessWidget {
intField: intField,
intFieldWithDefaultValue: intFieldWithDefaultValue,
intFieldWithSpace: newValue,
customField: customField,
customFieldWithDefaultValue: customFieldWithDefaultValue,
).go(context);
},
),
ListTile(
title: const Text('customField:'),
subtitle: Text(
customField == null ? '' : CustomParameter.encode(customField!),
),
trailing: const Icon(Icons.add),
onTap: () {
final newValue = CustomParameter(
valueString: '${customField?.valueString ?? ''}-',
valueInt: (customField?.valueInt ?? 0) + 1,
);
IntRoute(
intField: intField,
intFieldWithDefaultValue: intFieldWithDefaultValue,
intFieldWithSpace: intFieldWithSpace,
customField: newValue,
customFieldWithDefaultValue: customFieldWithDefaultValue,
).go(context);
},
),
ListTile(
title: const Text('customFieldWithDefaultValue:'),
subtitle: Text(CustomParameter.encode(customFieldWithDefaultValue)),
trailing: const Icon(Icons.add),
onTap: () {
final newValue = CustomParameter(
valueString: '${customFieldWithDefaultValue.valueString}-',
valueInt: customFieldWithDefaultValue.valueInt + 1,
);
IntRoute(
intField: intField,
intFieldWithDefaultValue: intFieldWithDefaultValue,
intFieldWithSpace: intFieldWithSpace,
customField: customField,
customFieldWithDefaultValue: newValue,
).go(context);
},
),
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/go_router_builder/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies:
collection: ^1.15.0
flutter:
sdk: flutter
go_router: ^17.1.0
go_router: ^17.2.0
provider: 6.0.5

dev_dependencies:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,23 @@ void main() {
);
expect(find.text('2'), findsOne);
});

testWidgets('It should modify the custom fields when tapped', (tester) async {
await tester.pumpWidget(App());

expect(find.text('customField:'), findsOne);
expect(find.text('customFieldWithDefaultValue:'), findsOne);

expect(find.text('default,0'), findsOne);

await tester.tap(find.text('customField:'));
await tester.pumpAndSettle();
expect(find.text('-,1'), findsOne);
expect(find.text('default,0'), findsOne);

await tester.tap(find.text('customFieldWithDefaultValue:'));
await tester.pumpAndSettle();
expect(find.text('-,1'), findsOne);
expect(find.text('default-,1'), findsOne);
});
}
4 changes: 1 addition & 3 deletions packages/go_router_builder/lib/src/route_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,7 @@ mixin _GoRouteMixin on RouteBaseConfig {
if (param.type.isNullableType) {
throw NullableDefaultValueError(param);
}
conditions.add(
compareField(param, parameterName, param.defaultValueCode!),
);
conditions.add(compareField(param));
} else if (param.type.isNullableType) {
conditions.add('$selfFieldName.$parameterName != null');
}
Expand Down
Loading
Loading