Skip to content

Commit de383e5

Browse files
authored
Merge pull request #19 from Exelord/feature-query-params
Custom Query Params
2 parents db5c993 + 62b1d5c commit de383e5

File tree

8 files changed

+60
-22
lines changed

8 files changed

+60
-22
lines changed

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ let user = this.get('currentUser');
4141
let postToPublish = this.get('store').findRecord('post', 1);
4242
let payload = { publisher: user };
4343

44-
postToPublish.publish(payload).then((status) => {
44+
postToPublish.publish(payload, /*{ custom options }*/).then((status) => {
4545
alert(`Post has been: ${status}`)
4646
}).catch((error) => {
4747
console.log('Here are you serialized model errors', error.serializedErrors);
@@ -70,7 +70,7 @@ let user = this.get('currentUser');
7070
let emptyPost = this.get('store').createRecord('post');
7171
let payload = { user };
7272

73-
emptyPost.favorites(payload).then((favoritesPosts) => {
73+
emptyPost.favorites(payload, /*{ custom options }*/).then((favoritesPosts) => {
7474
console.log(favoritesPosts);
7575
}).finally(()=>{
7676
emptyPost.deleteRecord();
@@ -175,6 +175,10 @@ model.customAction({}, { promiseType: null }) // returns Promise
175175
```
176176
`null` is useful if you don't care about the response or just want to use `then` on the promise without using `binding` or display it in the template.
177177

178+
#### `params`
179+
You can pass a query params for a request by passing an `{}` with properties, eg: `{ include: 'owner' }`
180+
** Remember: Query params are not normalized! You have to pass it in the correct format. **
181+
178182
# Development
179183

180184
## Installation

addon/actions/action.js

+14-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const {
77
assign,
88
getOwner,
99
computed,
10-
Object: emberObject,
10+
Object: EmberObject,
1111
ObjectProxy,
1212
ArrayProxy,
1313
PromiseProxyMixin,
@@ -21,14 +21,19 @@ const promiseTypes = {
2121
object: ObjectProxy.extend(PromiseProxyMixin)
2222
};
2323

24-
export default emberObject.extend({
24+
export default EmberObject.extend({
2525
model: null,
2626
options: {},
2727
payload: {},
2828
instance: false,
2929

3030
store: computed.reads('model.store'),
3131

32+
params: computed('config.params', 'adapter', function() {
33+
let params = emberTypeOf(this.get('config.params')) === 'object' ? this.get('config.params') : {};
34+
return this.get('adapter').sortQueryParams(params);
35+
}),
36+
3237
modelName: computed('model', function() {
3338
let { constructor } = this.get('model');
3439
return constructor.modelName || constructor.typeKey;
@@ -44,15 +49,15 @@ export default emberObject.extend({
4449

4550
appConfig: computed('model', function() {
4651
let config = getOwner(this.get('model')).resolveRegistration('config:environment').emberCustomActions || {};
47-
return emberObject.create(config);
52+
return EmberObject.create(config);
4853
}),
4954

5055
defaultConfig: computed(function() {
51-
return emberObject.create(defaultConfig);
56+
return EmberObject.create(defaultConfig);
5257
}),
5358

5459
config: computed('defaultConfig', 'options', 'appConfig', function() {
55-
return emberObject.create(assign(this.get('defaultConfig'), this.get('appConfig'), this.get('options')));
60+
return EmberObject.create(assign({}, this.get('defaultConfig'), this.get('appConfig'), this.get('options')));
5661
}),
5762

5863
requestType: computed('config.type', function() {
@@ -67,14 +72,16 @@ export default emberObject.extend({
6772
adapter: this.get('adapter'),
6873
urlType: this.get('urlType'),
6974
instance: this.get('instance'),
70-
model: this.get('model')
75+
model: this.get('model'),
76+
params: this.get('params')
7177
}).build();
7278
}),
7379

7480
data: computed('config.{normalizeOperation,ajaxOptions}', 'payload', function() {
7581
let payload = emberTypeOf(this.get('payload')) === 'object' ? this.get('payload') : {};
7682
let data = normalizePayload(payload, this.get('config.normalizeOperation'));
77-
return assign(this.get('config.ajaxOptions'), { data });
83+
84+
return assign({}, this.get('config.ajaxOptions'), { data });
7885
}),
7986

8087
promiseType: computed('config.promiseType', function() {

addon/actions/model.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default function(path, options = {}) {
88
return Action.create({
99
model: this,
1010
instance: true,
11-
options: assign(options, customOptions),
11+
options: assign({}, options, customOptions),
1212
payload,
1313
path
1414
}).callAction();

addon/actions/resource.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default function(path, options = {}) {
77
return function(payload = {}, customOptions = {}) {
88
return Action.create({
99
model: this,
10-
options: assign(options, customOptions),
10+
options: assign({}, options, customOptions),
1111
path,
1212
payload
1313
}).callAction();

addon/utils/url-builder.js

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import Ember from 'ember';
22

3-
const { assert, computed, Object } = Ember;
3+
const { assert, computed, Object: EmberObject, $ } = Ember;
4+
5+
export default EmberObject.extend({
6+
params: {},
47

5-
export default Object.extend({
68
modelName: computed('model', function() {
79
let { constructor } = this.get('model');
810
return constructor.modelName || constructor.typeKey;
@@ -21,14 +23,28 @@ export default Object.extend({
2123
},
2224

2325
_buildUrl(id) {
24-
return this.get('adapter').buildURL(this.get('modelName'), id, this.get('snapshot'), this.get('urlType'));
26+
let query = this.get('params');
27+
let snapshot = this.get('snapshot');
28+
let modelName = this.get('modelName');
29+
let requestType = this.get('urlType');
30+
31+
return this.get('adapter').buildURL(modelName, id, snapshot, requestType, query);
2532
},
2633

2734
_makeUrl(url) {
35+
let pathUrl = '';
36+
let query = $.param(this.get('params'));
37+
2838
if (url.charAt(url.length - 1) === '/') {
29-
return `${url}${this.get('path')}`;
39+
pathUrl = `${url}${this.get('path')}`;
40+
} else {
41+
pathUrl = `${url}/${this.get('path')}`;
42+
}
43+
44+
if (query) {
45+
return `${pathUrl}?${query}`;
3046
} else {
31-
return `${url}/${this.get('path')}`;
47+
return pathUrl;
3248
}
3349
}
3450
});

tests/dummy/app/models/post.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,9 @@ export default Model.extend({
88

99
publish: modelAction('publish', { promiseType: 'object' }),
1010
list: resourceAction('list'),
11-
search: resourceAction('search', { type: 'GET', normalizeOperation: 'dasherize' })
11+
search: resourceAction('search', {
12+
type: 'GET',
13+
normalizeOperation: 'dasherize',
14+
params: { showAll: true }
15+
})
1216
});

tests/unit/models/bike-test.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ moduleForModel('bike', 'Unit | Model | bike', {
1414
});
1515

1616
test('model action', function(assert) {
17-
assert.expect(3);
17+
assert.expect(4);
1818

1919
this.server.put('/bikes/:id/ride', (request) => {
2020
let data = JSON.parse(request.requestBody);
21+
2122
assert.deepEqual(data, { myParam: 'My first param' });
22-
assert.equal(request.url, '/bikes/1/ride');
23+
assert.deepEqual(request.queryParams, { enduro: 'true', include: 'owner' });
24+
assert.equal(request.url, '/bikes/1/ride?enduro=true&include=owner');
2325

2426
return [200, { }, 'true'];
2527
});
@@ -30,7 +32,7 @@ test('model action', function(assert) {
3032
let model = this.subject();
3133
model.set('id', 1);
3234

33-
model.ride(payload).then((response) => {
35+
model.ride(payload, { params: { enduro: true, include: 'owner' } }).then((response) => {
3436
assert.ok(response, true);
3537
done();
3638
});

tests/unit/models/post-test.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,16 @@ test('resource action', function(assert) {
8989
});
9090

9191
test('resource action with params in GET', function(assert) {
92-
assert.expect(3);
92+
assert.expect(4);
9393

9494
this.server.get('/posts/search', (request) => {
95-
assert.equal(request.url, '/posts/search?my-param=My%20first%20param');
95+
assert.equal(request.url, '/posts/search?showAll=true&my-param=My%20first%20param');
9696
assert.equal(request.requestHeaders.test, 'Custom header');
97+
assert.deepEqual(request.queryParams, {
98+
'my-param': 'My first param',
99+
'showAll': 'true'
100+
});
101+
97102
return [200, { }, 'true'];
98103
});
99104

0 commit comments

Comments
 (0)