Skip to content

[go_router_builder] Proposal: add json support, custom string encoder/decoder #8665

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

NearTox
Copy link

@NearTox NearTox commented Feb 20, 2025

Add initial json support for use in go_router_builder
Adds annotation that enable custom string encoder/decoder, its enable conversion for base64

This allow custom type conversion for parameters, like mentionated in #117261 and #110781

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@@ -6,6 +6,9 @@
/// deep linking, data-driven routes and more.
library go_router;

// used for json decoder/encoder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just import 'dart:convert'; in the file where you use it

class JsonExample {
const JsonExample({required this.id});

// mismach toJson
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: mismatch

const JsonExample({required this.id});

// mismach toJson
factory JsonExample.toJson(dynamic json) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean fromJson here ?


import 'package:go_router/go_router.dart';

@TypedGoRoute<BadJson>(path: '/')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BadJson-> rename it?

@hannah-hyj
Copy link
Member

you also need to bump versions in packages/go_router_builder/CHANGELOG.md and packages/go_router_builder/pubspec.yaml

}''';
}

bool _isTemplate(InterfaceType type) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_isTemplate : maybe rename to _isNestedTemplate?

@hannah-hyj
Copy link
Member

thank you for contributing the PR! This looks good to me over all with some comments


import 'package:go_router/go_router.dart';
// used for json decoder/encoder
export 'dart:convert' show jsonDecode, jsonEncode;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think you can just import it instead of export it?

@NearTox NearTox changed the title [go_router_builder] Proposal: add json support [go_router_builder] Proposal: add json support, custom string encoder/decoder Feb 26, 2025
@chunhtai chunhtai requested a review from hannah-hyj March 13, 2025 22:08
'`${type.getDisplayString(withNullability: false)}` not have a supported fromJson definition.',
element: type.element,
);
// return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// return false;

is this a typo?

Comment on lines 62 to 112
String? decoder;

final ElementAnnotation? annotation =
metadata?.firstWhereOrNull((ElementAnnotation annotation) {
return annotation.computeConstantValue()?.type?.getDisplayString() ==
'CustomParameterCodec';
});
if (annotation != null) {
final String? decode = annotation
.computeConstantValue()
?.getField('decode')
?.toFunctionValue()
?.displayName;
final String? encode = annotation
.computeConstantValue()
?.getField('encode')
?.toFunctionValue()
?.displayName;
if (decode != null && encode != null) {
decoder = decode;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: code here is same as L110-L129, you can extract them into a function to reuse.

String _encode(String fieldName, DartType type) =>
'$fieldName${type.ensureNotNull}.toString()';
String _encode(String fieldName, DartType type, String? customEncoder) {
String encode = '$fieldName${type.ensureNotNull}.toString()';
Copy link
Member

@hannah-hyj hannah-hyj Mar 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this could be:

   if (customEncoder != null) {
      return  '$customEncoder($encode)';
    }    
   return  '$fieldName${type.ensureNotNull}.toString()';

String _encode(String fieldName, DartType type) =>
'$fieldName${type.ensureNotNull}.toString()';
String _encode(String fieldName, DartType type, String? customEncoder) {
String encode = '$fieldName${type.ensureNotNull}.toString()';
Copy link
Member

@hannah-hyj hannah-hyj Mar 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ditto, and all other _encode

@hannah-hyj
Copy link
Member

PR looks good to me over all, just left some nit comments :)

@NearTox
Copy link
Author

NearTox commented Mar 19, 2025

I made a rebase in order to take in account latest changes from main branch

@chunhtai
Copy link
Contributor

looks like the ci is not happy

@NearTox
Copy link
Author

NearTox commented Mar 21, 2025

I think it’s because the annotations requires the changes that I made in go_router_builder.
When I tested locally was overriding the dependency.
I should add it?

@chunhtai
Copy link
Contributor

they will have to be separate into two prs. I think we try to avoid having one pr that bump the two package at once

@hannah-hyj hannah-hyj self-requested a review March 24, 2025 22:48
@hannah-hyj
Copy link
Member

Hi @NearTox , is this PR still on your radar? this pr has to be separated into 2 PRs for go_router and go_router_builder

@NearTox
Copy link
Author

NearTox commented Jun 7, 2025

Hi @hannah-hyj , sorry for the delayed reply.
I splitted into two PR (chained commits)
I made a rebase in order to reach the last version of the go_router_builder

@Piinks
Copy link
Contributor

Piinks commented Jun 18, 2025

Thanks for the updates, and for contributing @NearTox! It looks like this is currently failing a lot of tests, can you take a look?

Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review, I think the overall approach looks fine, but can you add a example usage for custom codec?

@@ -191,3 +191,46 @@ class Repository {
return FamilyPerson(family: family, person: family.person(pid));
}
}

class JsonExample {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move this to json_example.dart

final ElementAnnotation? annotation =
metadata?.firstWhereOrNull((ElementAnnotation annotation) {
final DartObject? constant = annotation.computeConstantValue();
return constant?.type?.getDisplayString() == 'CustomParameterCodec';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add an example for using custom codec?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants