Skip to content

Commit 47739d5

Browse files
authored
Merge pull request #5 from Exelord/feature-promise-types
Add posibility to bind results
2 parents 499776c + 32a57d9 commit 47739d5

File tree

10 files changed

+110
-16
lines changed

10 files changed

+110
-16
lines changed

README.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ module.exports = function(environment) {
8181
type: 'PUT',
8282
ajaxOptions: {},
8383
pushToStore: false,
84-
normalizeOperation: ''
84+
normalizeOperation: '',
85+
promiseType: null
8586
},
8687
};
8788

@@ -133,6 +134,27 @@ It's great for API with request data format restrictions
133134
- decamelize
134135
- underscore
135136

137+
138+
#### `promiseType`
139+
You can easily observe a returned model by changing promiseType to `array` or `object` according to what type of data
140+
your server will return.
141+
142+
When `array`:
143+
```js
144+
model.customAction({}, { promiseType: 'array' }) // returns DS.PromiseArray
145+
```
146+
147+
When `object`:
148+
```js
149+
model.customAction({}, { promiseType: 'object' }) // returns DS.PromiseObject
150+
```
151+
152+
When `null` (default):
153+
```js
154+
model.customAction({}, { promiseType: null }) // returns Promise
155+
```
156+
`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.
157+
136158
# Development
137159

138160
## Installation

addon/actions/action.js

+20-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1+
/* eslint ember-suave/no-direct-property-access:1 */
2+
13
import Ember from 'ember';
4+
import DS from 'ember-data';
5+
26
import UrlBuilder from '../utils/url-builder';
37
import normalizePayload from '../utils/normalize-payload';
48
import defaultConfig from '../config';
59

6-
const { assign, getOwner, computed, isArray, ArrayProxy, ObjectProxy, Object } = Ember;
10+
const { assign, getOwner, computed, Object } = Ember;
11+
12+
const promiseTypes = {
13+
array: DS.PromiseArray,
14+
object: DS.PromiseObject
15+
};
716

817
export default Object.extend({
918
model: null,
@@ -61,18 +70,22 @@ export default Object.extend({
6170
return assign(this.get('config.ajaxOptions'), { data });
6271
}),
6372

73+
promiseType: computed('config.promiseType', function() {
74+
return promiseTypes[this.get('config.promiseType')];
75+
}),
76+
6477
callAction() {
78+
let promise = this._promise();
79+
return this.get('promiseType') ? this.get('promiseType').create({ promise }) : promise;
80+
},
81+
82+
_promise() {
6583
return this.get('adapter').ajax(this.get('url'), this.get('requestType'), this.get('data')).then((response) => {
6684
if (this.get('config.pushToStore') && response.data) {
67-
return this._pushToStore(this.get('serializer').pushPayload(this.get('store'), response));
85+
return this.get('serializer').pushPayload(this.get('store'), response);
6886
} else {
6987
return response;
7088
}
7189
});
72-
},
73-
74-
_pushToStore(content) {
75-
let proxy = isArray(content) ? ArrayProxy : ObjectProxy;
76-
return proxy.create({ content });
7790
}
7891
});

addon/config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export default {
22
type: 'PUT',
33
ajaxOptions: {},
44
pushToStore: false,
5-
normalizeOperation: ''
5+
normalizeOperation: '',
6+
promiseType: null
67
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Ember from 'ember';
2+
3+
const { Component, inject, computed } = Ember;
4+
5+
export default Component.extend({
6+
store: inject.service(),
7+
8+
post: computed('property', function() {
9+
return this.get('store').createRecord('post', { id: 1 });
10+
}),
11+
12+
status: computed('post', function() {
13+
return this.get('post').publish();
14+
})
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{status.published}}

tests/dummy/app/models/post.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import Model from 'ember-data/model';
2+
import attr from 'ember-data/attr';
23
import { modelAction, resourceAction } from 'ember-custom-actions';
34

45
export default Model.extend({
5-
publish: modelAction('publish'),
6+
name: attr(),
7+
published: attr(),
8+
9+
publish: modelAction('publish', { promiseType: 'object' }),
610
list: resourceAction('list'),
711
search: resourceAction('search', { type: 'GET', normalizeOperation: 'dasherize' })
812
});

tests/dummy/app/routes/application.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Ember from 'ember';
2+
import Pretender from 'pretender';
3+
4+
const { Route } = Ember;
5+
6+
export default Route.extend({
7+
init() {
8+
this._super(...arguments);
9+
this.server = new Pretender();
10+
this.mockServer();
11+
},
12+
13+
mockServer() {
14+
this.server.put('/posts/:id/publish', (request) => {
15+
return [200, {}, `{"data": {"id": ${request.params.id}, "type": "Post", "attributes": {"published": true}}}`];
16+
});
17+
}
18+
});
+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
{{!-- The following component displays Ember's default welcome message. --}}
2-
{{welcome-page}}
3-
{{!-- Feel free to remove this! --}}
4-
5-
{{outlet}}
1+
{{model-action}}

tests/dummy/app/templates/components/.gitkeep

Whitespace-only changes.

tests/unit/models/post-test.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/* eslint ember-suave/no-direct-property-access:1 */
2+
3+
import Ember from 'ember';
4+
import DS from 'ember-data';
15
import { moduleForModel, test } from 'ember-qunit';
26
import Pretender from 'pretender';
37

@@ -125,8 +129,28 @@ test('resource action pushes to store', function(assert) {
125129
assert.equal(store.peekAll('post').get('length'), 1);
126130

127131
model.list(payload).then((response) => {
128-
assert.equal(response.get('length'), 2);
132+
assert.equal(response.length, 2);
129133
assert.equal(store.peekAll('post').get('length'), 3);
130134
done();
131135
});
132136
});
137+
138+
test('promiseTypes', function(assert) {
139+
assert.expect(6);
140+
141+
this.server.put('/posts/list', (request) => {
142+
assert.equal(request.url, '/posts/list');
143+
144+
return [200, {}, '{"data": [{"id": "2", "type": "post"},{"id": "3", "type": "post"}]}'];
145+
});
146+
147+
let model = this.subject();
148+
149+
let promise = model.list();
150+
let promiseArray = model.list(null, { promiseType: 'array' });
151+
let promiseObject = model.list(null, { promiseType: 'object' });
152+
153+
assert.equal(promise.constructor, Ember.RSVP.Promise);
154+
assert.equal(promiseArray.constructor, DS.PromiseArray);
155+
assert.equal(promiseObject.constructor, DS.PromiseObject);
156+
});

0 commit comments

Comments
 (0)