thanks @denisnazarov for tracking this one down.
ping señor @machty
@machty we could use your help on this
So after struggling with this last night I'm not sure that this is totally undesirable. Say you have the following controller.
App.MyController = Ember.Controller.extend({
queryParams: ['filters'],
filters: ['starred']
});
If you set filters
to null
and refresh the page what is the expected behavior? If you don't seralize null
into the url the controller property will be set to its default value.
This is similar to the problem in the previous implementation that it was ambiguous between falsy values and the actual value of false. Now it seems its ambiguous between a defaultValue
and null
or undefined
.
Here's another example using boolean query params: http://emberjs.jsbin.com/hamev/2/edit
If the default value is set to null
, setting it to true
or false
actually sets it to the string version, 'true'
or 'false'
.
@HeroicEric so what's the compelling reason for setting it to null
if in it's life time it's going to be the boolean true
/ false
?
That might have come out wrong; I'm just curious what the use cases are for all these serialization corner cases.
@machty I tried to show an example use case in the jsbin.
For example, I'm displaying a list of users and I want to be able to filter them so that the list contains either All Users, Admin Users, or Non-Admin Users. When I want to see All Users I would basically just be removing the filter.
Are situations like this not what query params are meant for?
Ideally the URLs would be something like this:
/users shows all the users
/users?admin=true shows all the admins
/users?admin=false shows all the users that are not admins
@HeroicEric @machty I think the idea was that if the defaultValue on the controller wasn't defined (null
or undefined
) that it would default to using strings. This would explain why true
and false
end up as their string versions since the serialization defaults to strings.
I think if you want a property to be set to null
then we need to get the type from somewhere else. @machty would this be a good reason for the ability of adding the type to the queryParams
configuration on the route?
If we had this then you could set the type as 'boolean
' and set the default to null
.
I have this JSBin example, and I wonder if what I'm seeing is related to this issue:
http://jsbin.com/dipajezi/1/edit
Basically, I have this foo
query parameter with a null
default value, and the first time my model hook gets called when the application starts, the value of the parameter is null
. When the parameter value is null
, I do not want to use this parameter to query the server, because it means "no value".
Query: ?page=1
When I click on the NextPage button, I transition again but this time I change the page
query parameter. This time the foo
query parameter has a string value of "null"
, which is kind of weird. In this case I would still want to have a value of null
, so that I can easily verifiy that the parameter does not have a value.
Query: ?page=1
and not ?page=1&foo=null
Finally, when I click on the ChangeFoo
button, I transition again, this time setting the value of the foo
query parameter to whatever value. Now that the value is not null, I can use this value to construct my query string.
Query ?page=1&foo=3
@raytiley Just wrote a note on https://github.com/raytiley/ember.js/commit/26a3f8569edb58f8644ce4f9cec7000276c327a6#diff-0631ecfe6138cf2c2eb2d94369c3e846R1640.
If I set a qp to null
explicitly, then it is cast to a string in the model hook. This doesn't seem right, since null
should represent "no value", and if an individual does want the null string, then they can create it based on the value null
.
Otherwise if you want to pass QPs that have values only, you have to do params.myQP && params.myQp !== "null"
..
I think this is out of date but will reopen if someone can demonstrate the issue in a JSBin that uses the following ember.js: http://s3.amazonaws.com/machty/to_s3_uploads/ember-9fbe6c2a-c124-5c2e-0414-f5ed36c2a1a2.js
_In case anyone find this via Google._
The issue is basically solved, but an edge case remain where if the query param isn't set on the controller it will serialize null
into 'null'
.
var AnimalsController = Ember.Controller.extend({
queryParams: ['myCat']
// myCat: null // deliberately not set, to illustrate the issue
});
export default AnimalsController;
Regarding @HeroicEric's use case, the controller won't know how to intelligently serialize based on what the value will be in its lifetime. This seems to be working in the most recent version (2.6):
export default Ember.Controller.extend({
queryParams: [{
redevelopment: {
type: 'boolean'
}
}],
redevelopment: null
});
Working ember twiddle: https://ember-twiddle.com/3afa1091106a91ce2c1734ae2998bc3f?openFiles=controllers.application.js%2C&route=%2F%3Fredevelopment%3Dtrue
Since when do QPs allow setting the type? Or are you just proposing a new API?
It seems to be undocumented. Looking here, it seems it can be overridden.
Oh, that's nice!
Thanks, @allthesignals, it's so helpful for your solution.
How about this solution?
{ key: undefined }
to ?
_(not included)_
{ key: null }
to ?key
{ key: '' }
to ?key=
{ key: 'null' }
to ?key=null
Good list!
I'd vote for this:
{ key: undefined }
to [nothing]
_(not included)_
{ key: null }
to [nothing]
_(not included)_
{ key: '' }
to ?key
{ key: 'null' }
to ?key=null
and possibly also:
{ key: false }
to [nothing]
_(not included)_
{ key: true }
to ?key
Most helpful comment
_In case anyone find this via Google._
The issue is basically solved, but an edge case remain where if the query param isn't set on the controller it will serialize
null
into'null'
.