Skip to content

Commit b7ea035

Browse files
leeyehwangxiao
authored andcommitted
feat(Object): add AV.Object.fetchAll (#327)
* fix(Request): remove duplicated getServerURLPromise resolving * feat(Object): add AV.Object.fetchAll
1 parent f951523 commit b7ea035

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

src/object.js

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,42 @@ module.exports = function(AV) {
115115
return AV.Object._deepSaveAsync(list, null, options)._thenRunCallbacks(options);
116116
};
117117

118+
/**
119+
* Fetch the given list of AV.Object.
120+
*
121+
* @param {AV.Object[]} objects A list of <code>AV.Object</code>
122+
* @param {Object} options
123+
* @param {String} options.sessionToken specify user's session, used in LeanEngine.
124+
* @return {Promise.<AV.Object[]>} The given list of <code>AV.Object</code>, updated
125+
*/
126+
127+
AV.Object.fetchAll = (objects, options) =>
128+
AV.Promise.as().then(() =>
129+
AVRequest('batch', null, null, 'POST', {
130+
requests: _.map(objects, object => {
131+
if (!object.className) throw new Error('object must have className to fetch');
132+
if (!object.id) throw new Error('object must have id to fetch');
133+
if (object.dirty()) throw new Error('object is modified but not saved');
134+
return {
135+
method: 'GET',
136+
path: `/1.1/classes/${object.className}/${object.id}`,
137+
};
138+
}),
139+
}, options && options.sessionToken)
140+
).then(function(response) {
141+
_.forEach(objects, function(object, i) {
142+
if (response[i].success) {
143+
object._finishFetch(
144+
object.parse(response[i].success));
145+
} else {
146+
const error = new Error(response[i].error.error);
147+
error.code = response[i].error.code;
148+
throw error;
149+
}
150+
});
151+
return objects;
152+
});
153+
118154
// Attach all inheritable methods to the AV.Object prototype.
119155
_.extend(AV.Object.prototype, AV.Events,
120156
/** @lends AV.Object.prototype */ {
@@ -574,7 +610,7 @@ module.exports = function(AV) {
574610
* @param {Object} options A set of Backbone-like options for the set.
575611
* The only supported options are <code>silent</code>,
576612
* <code>error</code>, and <code>promise</code>.
577-
* @return {Boolean} true if the set succeeded.
613+
* @return {AV.Object} self if succeeded, false if the value is not valid.
578614
* @see AV.Object#validate
579615
* @see AVError
580616
*/
@@ -1258,7 +1294,7 @@ module.exports = function(AV) {
12581294
};
12591295
/**
12601296
* Delete objects in batch.The objects className must be the same.
1261-
* @param {Array} The ParseObject array to be deleted.
1297+
* @param {Array} The <code>AV.Object</code> array to be deleted.
12621298
* @param {Object} options Standard options object with success and error
12631299
* callbacks.
12641300
* @return {AV.Promise} A promise that is fulfilled when the save

src/request.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ const setServerUrlByRegion = (region = 'cn') => {
256256
Cache.getAsync('APIServerURL').then((serverURL) => {
257257
if (serverURL) {
258258
setServerUrl(serverURL);
259-
getServerURLPromise.resolve();
260259
} else {
261260
return refreshServerUrlByRouter();
262261
}

test/object.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,51 @@ describe('Objects', function(){
142142
});
143143
});
144144

145+
describe('Fetching Objects', () => {
146+
it('fetch', () =>
147+
AV.Object.createWithoutData('GameScore', gameScore.id).fetch().then(score => {
148+
expect(score.get('score')).to.be.a('number');
149+
expect(score.createdAt).to.be.a(Date);
150+
expect(score.id).to.be.eql(gameScore.id);
151+
})
152+
);
153+
it('fetchAll', () =>
154+
AV.Object.fetchAll([
155+
AV.Object.createWithoutData('GameScore', gameScore.id),
156+
AV.Object.createWithoutData('GameScore', gameScore.id),
157+
]).then(([score1, score2]) => {
158+
expect(score1.get('score')).to.be.a('number');
159+
expect(score1.createdAt).to.be.a(Date);
160+
expect(score1.id).to.be.eql(gameScore.id);
161+
expect(score2.get('score')).to.be.a('number');
162+
expect(score2.createdAt).to.be.a(Date);
163+
expect(score2.id).to.be.eql(gameScore.id);
164+
})
165+
);
166+
it('fetchAll with non-existed Class should fail', (done) =>
167+
AV.Object.fetchAll([
168+
AV.Object.createWithoutData('GameScore', gameScore.id),
169+
AV.Object.createWithoutData('FakeClass', gameScore.id),
170+
]).then(function() {
171+
done(new Error(`should be rejected`));
172+
}, function(err) {
173+
expect(err).to.be.an(Error);
174+
done();
175+
})
176+
);
177+
it('fetchAll with dirty objet should fail', (done) =>
178+
AV.Object.fetchAll([
179+
AV.Object.createWithoutData('GameScore', gameScore.id),
180+
new GameScore(),
181+
]).then(function() {
182+
done(new Error(`should be rejected`));
183+
}, function(err) {
184+
expect(err).to.be.an(Error);
185+
done();
186+
})
187+
);
188+
});
189+
145190
describe("Deleting Objects",function(){
146191
it("should delete cheatMode",function(done){
147192
gameScore.unset("cheatMode");

0 commit comments

Comments
 (0)