-
Notifications
You must be signed in to change notification settings - Fork 27.5k
fix($httpParamSerializerJQLike): call functions as jQuery does #16139
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no tests with functions inside arrays 😞
Can you also change the commit message to make it more clear that previously function were stringified (not ignored). This will make it easier for people understand what differences to expect.
src/ng/http.js
Outdated
@@ -122,8 +122,12 @@ function $HttpParamSerializerJQLikeProvider() { | |||
(topLevel ? '' : ']')); | |||
}); | |||
} else { | |||
parts.push(encodeUriQuery(prefix) + '=' + | |||
(toSerialize == null ? '' : encodeUriQuery(serializeValue(toSerialize)))); | |||
if (isFunction(toSerialize)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EDIT: This comment is now obsolete.
Merge with the else
above for consistency:
...
} else if (isFunction(toSerialize)) {
...
} else {
...
}
test/ng/httpSpec.js
Outdated
expect(jqrSer({a: function() { return { b: 'c' }; }, foo: {'bar': 'barv', 'baz': 'bazv'}})).toEqual( | ||
'a%5Bb%5D=c&foo%5Bbar%5D=barv&foo%5Bbaz%5D=bazv'); | ||
//a[b]=c&foo[bar]=barv&foo[baz]=bazv | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two tests are testing more (independent) things than necessary. They should focus on the function
part. The rest is irrelevant.
test/ng/httpSpec.js
Outdated
//a=b&foo[bar]=barv&foo[baz]=bazv | ||
}); | ||
|
||
it('should serialize nested objects with function properties returning an object by repeating param name with [key] suffix', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/ng/http.js
Outdated
parts.push(encodeUriQuery(prefix) + '=' + | ||
(toSerialize == null ? '' : encodeUriQuery(serializeValue(toSerialize)))); | ||
if (isFunction(toSerialize)) { | ||
serialize(toSerialize(), prefix); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this is not how jQuery does it. They do not recursively serialize a returned object. They just use the returned value.
Updated the PR, added a test for a function in an array aswell! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add some test for array inside object (e.g. {foo: {bar: [valueFn('baz')]}}
).
src/ng/http.js
Outdated
} else { | ||
parts.push(encodeUriQuery(prefix) + '=' + | ||
(toSerialize == null ? '' : encodeUriQuery(serializeValue(toSerialize)))); | ||
(toSerialize == null ? '' : encodeUriQuery(serializeValue(toSerialize)))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong indentation 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, you can avoid code duplication with:
...
} else {
if (isFunction(toSerialize)) {
toSerialize = toSerialize();
}
parts.push(encodeUriQuery(prefix) + '=' +
(toSerialize == null ? '' : encodeUriQuery(serializeValue(toSerialize))));
}
test/ng/httpSpec.js
Outdated
@@ -2364,17 +2364,45 @@ describe('$http param serializers', function() { | |||
expect(decodeURIComponent(jqrSer({a: 'b', foo: ['bar', 'baz']}))).toEqual('a=b&foo[]=bar&foo[]=baz'); | |||
}); | |||
|
|||
it('should serialize arrays with functions', function() { | |||
expect(jqrSer({foo:[function() { return 'bar'; }]})).toEqual('foo%5B%5D=bar'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space after :
. 😁
BTW, you an probably use valueFn('bar')
to save some typing 😎
test/ng/httpSpec.js
Outdated
it('should serialize objects by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({a: 'b', foo: {'bar': 'barv', 'baz': 'bazv'}})).toEqual('a=b&foo%5Bbar%5D=barv&foo%5Bbaz%5D=bazv'); | ||
//a=b&foo[bar]=barv&foo[baz]=bazv | ||
}); | ||
|
||
it('should serialize objects with function properties by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({a: function() { return 'b'; }})).toEqual( | ||
'a=b'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the "by repeating param name with [key] suffix" part, which is irrelevant (here and below).
Weird line-splitting (here and below) 😕
test/ng/httpSpec.js
Outdated
it('should serialize objects with function properties returning an object by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({a: function() { return { b: 'c' }; }})).toEqual( | ||
'a=%7B%22b%22:%22c%22%7D'); | ||
//a={"b": "c"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no space after :
.
test/ng/httpSpec.js
Outdated
|
||
it('should serialize objects with function properties returning an object by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({a: function() { return { b: 'c' }; }})).toEqual( | ||
'a=%7B%22b%22:%22c%22%7D'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not exactly how jQuery does it, but that is not related to this PR 😁
test/ng/httpSpec.js
Outdated
it('should serialize nested objects with function properties returning an object by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({foo: {'bar': function() { return { bav: 'barv' }; }}})).toEqual( | ||
'foo%5Bbar%5D=%7B%22bav%22:%22barv%22%7D'); | ||
//foo[bar]={"bav": "barv"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No space after :
.
test/ng/httpSpec.js
Outdated
it('should serialize nested objects by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({a: ['b', {c: 'd'}], e: {f: 'g', 'h': ['i', 'j']}})).toEqual( | ||
'a%5B%5D=b&a%5B1%5D%5Bc%5D=d&e%5Bf%5D=g&e%5Bh%5D%5B%5D=i&e%5Bh%5D%5B%5D=j'); | ||
//a[]=b&a[1][c]=d&e[f]=g&e[h][]=i&e[h][]=j | ||
}); | ||
|
||
it('should serialize nested objects with function properties by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({foo: {'bar': function() { return 'barv'; }}})).toEqual( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for quoting bar
(here and below).
Updated! |
src/ng/http.js
Outdated
parts.push(encodeUriQuery(prefix) + '=' + | ||
(toSerialize == null ? '' : encodeUriQuery(serializeValue(toSerialize)))); | ||
(toSerialize == null ? '' : encodeUriQuery(serializeValue(toSerialize)))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong indentation. 😞
test/ng/httpSpec.js
Outdated
it('should serialize nested objects with function properties by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({foo: {'bar': function() { return 'barv'; }}})).toEqual( | ||
it('should serialize nested objects with function properties', function() { | ||
expect(jqrSer({foo: {bar: valueFn('barv')}})).toEqual( | ||
'foo%5Bbar%5D=barv'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird line break (here and below) 😕
test/ng/httpSpec.js
Outdated
it('should serialize nested objects with function properties returning an object by repeating param name with [key] suffix', function() { | ||
expect(jqrSer({foo: {'bar': function() { return { bav: 'barv' }; }}})).toEqual( | ||
it('should serialize nested objects with function properties returning an object', function() { | ||
expect(jqrSer({foo: {bar: valueFn({ bav: 'barv' })}})).toEqual( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent whitespace after {
and before }
😁
Previously, `httpParamSerializerJQLike` stringified function properties without executing them. This commit ensures function properties are executed and the return value is used. Closes #16138
test/ng/httpSpec.js
Outdated
@@ -2364,17 +2364,41 @@ describe('$http param serializers', function() { | |||
expect(decodeURIComponent(jqrSer({a: 'b', foo: ['bar', 'baz']}))).toEqual('a=b&foo[]=bar&foo[]=baz'); | |||
}); | |||
|
|||
it('should serialize arrays with functions', function() { | |||
expect(jqrSer({foo: [valueFn('bar')]})).toEqual('foo%5B%5D=bar'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where's the decoded comment (foo[]=bar
)? 😁
test/ng/httpSpec.js
Outdated
expect(jqrSer({a: valueFn('b')})).toEqual('a=b'); | ||
}); | ||
|
||
it('should serialize objects with function properties returning an object by repeating param name with [key] suffix', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inaccurate description.
test/ng/httpSpec.js
Outdated
}); | ||
|
||
it('should serialize nested objects with function properties returning an object', function() { | ||
expect(jqrSer({foo: {bar: valueFn({ bav: 'barv'})}})).toEqual('foo%5Bbar%5D=%7B%22bav%22:%22barv%22%7D'); //foo[bar]={"bav":"barv"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra whitespace in { bav
. 😱
Merging to master only, since it has already deviated from 1.6.x (not converting empty strings to |
Closes #16138
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix
What is the current behavior? (You can also link to an open issue here)
Previously,
httpParamSerializerJQLike
did not handle properties of type function.What is the new behavior (if this is a feature change)?
This commit ensures function properties are executed and the return value is used.
Does this PR introduce a breaking change?
See: #16138 (comment)
Please check if the PR fulfills these requirements
Other information: