-
Notifications
You must be signed in to change notification settings - Fork 11
/
ampersand-collection-rest-mixin.js
126 lines (108 loc) · 4.37 KB
/
ampersand-collection-rest-mixin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*$AMPERSAND_VERSION*/
var sync = require('ampersand-sync');
var assign = require('lodash/assign');
module.exports = {
// Fetch the default set of models for this collection, resetting the
// collection when they arrive. If `reset: true` is passed, the response
// data will be passed through the `reset` method instead of `set`.
fetch: function(options) {
options = options ? assign({}, options) : {};
if (options.parse === void 0) options.parse = true;
var self = this;
var success = options.success;
options.success = function(resp) {
var method = options.reset ? 'reset' : 'set';
if (options.set !== false) self[method](resp, options);
if (success) success(self, resp, options);
if (options.set !== false) self.trigger('sync', self, resp, options);
};
// Wrap an optional error callback with a fallback error event.
var error = options.error;
options.error = function(resp) {
if (error) error(self, resp, options);
self.trigger('error', self, resp, options);
};
var request = this.sync('read', this, options);
// Make the request available on the options object so it can be accessed
// further down the line by `parse`, sync listeners, etc
// https://github.com/AmpersandJS/ampersand-collection-rest-mixin/commit/d32d788aaff912387eb1106f2d7ad183ec39e11a#diff-84c84703169bf5017b1bc323653acaa3R32
options.xhr = request;
return request;
},
// Create a new instance of a model in this collection. Add the model to the
// collection immediately, unless `wait: true` is passed, in which case we
// wait for the server to agree.
create: function(model, options) {
options = options ? assign({}, options) : {};
if (!(model = this._prepareModel(model, options))) return false;
if (!options.wait) this.add(model, options);
var self = this;
var success = options.success;
options.success = function(model, resp) {
if (options.wait) self.add(model, options);
if (success) success(model, resp, options);
};
model.save(null, options);
return model;
},
sync: function() {
return sync.apply(this, arguments);
},
// Get or fetch a model by Id.
getOrFetch: function (id, options, cb) {
if (arguments.length !== 3) {
cb = options;
options = {};
}
var self = this;
var model = this.get(id);
if (model) {
return window.setTimeout(cb.bind(null, null, model), 0);
}
if (options.all) {
//preserve original `options.always`
var always = options.always;
options.always = function(err, resp, body) {
if (always) always(err, resp, body);
if (!cb) return;
var model = self.get(id);
var err2 = model ? null : new Error('not found');
cb(err2, model);
};
return this.fetch(options);
} else {
return this.fetchById(id, options, cb);
}
},
// fetchById: fetches a model and adds it to
// collection when fetched.
fetchById: function (id, options, cb) {
if (arguments.length !== 3) {
cb = options;
options = {};
}
var self = this;
var idObj = {};
idObj[this.mainIndex] = id;
var model = new this.model(idObj, {collection: this});
//preserve original `options.success`
var success = options.success;
options.success = function (resp) {
model = self.add(model);
if (success) success(self, resp, options);
if (cb) cb(null, model);
};
//preserve original `options.error`
var error = options.error;
options.error = function (collection, resp) {
delete model.collection;
if (error) error(collection, resp, options);
if (cb) {
var err = new Error(resp.rawRequest.statusText);
err.status = resp.rawRequest.status;
cb(err);
}
};
return model.fetch(options);
}
};