Skip to content
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

[BUGFIX release] Prevent multiple qp serialization on activeTransition #19236

Merged

Conversation

rreckonerr
Copy link
Contributor

@rreckonerr rreckonerr commented Oct 28, 2020

We're using serialized query parameters for active transition instead of deserialized ones. This results in multiple serialization of qp's.

Closes #14174

...on activeTransition in `_doTransition`.
`_processActiveTransitionQueryParams` returns serialized values and we serialize them again in `_prepareQueryParams`, which expects deserialized values.

Refs: emberjs#14174
We're using serialized query parameters for active transition instead of deserialized ones. This results in multiple serialization of QP's.
@rreckonerr rreckonerr force-pushed the fix/active-transition-qp-serialization branch from f8ed040 to 20da5b2 Compare October 31, 2020 11:48
@rreckonerr rreckonerr changed the title [WIP] Prevent double qp serialization Prevent double qp serialization Oct 31, 2020
Comment on lines +140 to +170
['@test Calling transitionTo does not serialize query params already serialized on the activeTransition'](
assert
) {
assert.expect(3);

this.router.map(function () {
this.route('parent', function () {
this.route('child');
this.route('sibling');
});
});

this.add(
'route:parent.child',
Route.extend({
afterModel() {
this.transitionTo('parent.sibling');
},
})
);

this.add(
'controller:parent',
Controller.extend({
queryParams: ['array', 'string'],
array: [],
string: '',
})
);

// `/parent/child?array=["one",2]&string=hello`
Copy link
Contributor Author

@rreckonerr rreckonerr Oct 31, 2020

Choose a reason for hiding this comment

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

@chancancode @rwjblue

This test case fails with not really helpful error:

Promise rejected during " Calling transitionTo does not serialize multiple times query params already on the activeTransition": Assertion Failed: Cannot call `meta` on string
Error message image

Which comes from emberA trying to convert a string to array.

emberA(JSON.parse(value as string)`

_deserializeQueryParam(value: unknown, defaultType: string) {
if (value === null || value === undefined) {
return value;
} else if (defaultType === 'boolean') {
return value === 'true';
} else if (defaultType === 'number') {
return Number(value).valueOf();
} else if (defaultType === 'array') {
return emberA(JSON.parse(value as string));
}
return value;
}

But this error is not thrown in an ember application.

Wrapping emberA(JSON.parse(value as string) in a try-catch block results in a readable failing test assertion, like that the expected route qp's are different from the actual ones.

Should we do something to improve error reporting in _deserializeQueryParam? Like, check if JSON.parse(value) actually returns an array?

Copy link
Member

Choose a reason for hiding this comment

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

Should we do something to improve error reporting in _deserializeQueryParam? Like, check if JSON.parse(value) actually returns an array?

Yes, I think this seems like the best path.

@rreckonerr rreckonerr changed the title Prevent double qp serialization [BUGFIX] Prevent double qp serialization Oct 31, 2020
@rreckonerr rreckonerr changed the title [BUGFIX] Prevent double qp serialization [BUGFIX] Prevent multiple qp serialization on activeTransition Oct 31, 2020
Comment on lines +140 to +170
['@test Calling transitionTo does not serialize query params already serialized on the activeTransition'](
assert
) {
assert.expect(3);

this.router.map(function () {
this.route('parent', function () {
this.route('child');
this.route('sibling');
});
});

this.add(
'route:parent.child',
Route.extend({
afterModel() {
this.transitionTo('parent.sibling');
},
})
);

this.add(
'controller:parent',
Controller.extend({
queryParams: ['array', 'string'],
array: [],
string: '',
})
);

// `/parent/child?array=["one",2]&string=hello`
Copy link
Member

Choose a reason for hiding this comment

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

Should we do something to improve error reporting in _deserializeQueryParam? Like, check if JSON.parse(value) actually returns an array?

Yes, I think this seems like the best path.

@rwjblue rwjblue changed the title [BUGFIX] Prevent multiple qp serialization on activeTransition [BUGFIX release] Prevent multiple qp serialization on activeTransition Nov 9, 2020
@rwjblue rwjblue merged commit 58daeff into emberjs:master Nov 9, 2020
@rwjblue rwjblue added the Bug label Nov 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Correct Query String Serialization and Deserialization
2 participants