Skip to content

Commit c6e78f9

Browse files
committed
Auto-resolve promises in data on request
1 parent cb2dfb3 commit c6e78f9

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

lib/client.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ Client.prototype.request = function(method, url, data, callback) {
143143
this.connect();
144144
}
145145

146+
// Resolve data as promised
147+
var promises = this.promisifyData(data);
148+
if (promises.length) {
149+
return Promise.all(promises).bind(this).then(function() {
150+
this.request(method, url, data, callback);
151+
});
152+
}
153+
146154
// Prepare url and data for request
147155
url = url && url.toString ? url.toString() : '';
148156
data = {$data: data};
@@ -186,6 +194,47 @@ Client.prototype.request = function(method, url, data, callback) {
186194
});
187195
};
188196

197+
/**
198+
* Resolve and return promises array from data
199+
* Only resolve top level object keys
200+
*
201+
* @param object data
202+
* @return array
203+
*/
204+
Client.prototype.promisifyData = function(data) {
205+
206+
if (!data) {
207+
return [];
208+
}
209+
210+
function thenResolvePromisedValue(data, key) {
211+
data[key].then(function(val) {
212+
data[key] = val;
213+
});
214+
}
215+
216+
var promises = [];
217+
if (typeof data === 'object') {
218+
var keys = Object.keys(data);
219+
for (var i = 0; i < keys.length; i++) {
220+
var key = keys[i];
221+
if (data[key] && data[key].then) {
222+
promises.push(data[key]);
223+
thenResolvePromisedValue(data, key);
224+
}
225+
}
226+
} else if (data instanceof Array) {
227+
for (var i = 0; i < data.length; i++) {
228+
if (data[i] && data[i].then) {
229+
promises.push(data[i]);
230+
thenResolvePromisedValue(data, i);
231+
}
232+
}
233+
}
234+
235+
return promises;
236+
};
237+
189238
/**
190239
* Client response handler
191240
*

lib/schema.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,9 @@ Record.prototype.__initLinks = function(links) {
12441244
res.__client.get(url, null, callback);
12451245
return this;
12461246
};
1247+
if (res[key] === undefined) {
1248+
return;
1249+
}
12471250
// record.link.each(...)
12481251
res[key].each = function(callback, then) {
12491252
if (typeof callback !== 'function') return;

test/client.spec.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,36 @@ describe('Client', function() {
325325
assert.strictEqual(calledBack, true);
326326
});
327327
});
328+
329+
it('resolves promised data (object)', function() {
330+
var data = {
331+
test1: Promise.resolve('hello'),
332+
test2: Promise.resolve('world'),
333+
test3: 'static'
334+
};
335+
336+
return client.request('get', 'url', data).then(function() {
337+
assert.deepEqual(serverRequestStub.args[0][2].$data, {
338+
test1: 'hello',
339+
test2: 'world',
340+
test3: 'static'
341+
});
342+
});
343+
});
344+
345+
it('resolves promised data (array)', function() {
346+
var data = [
347+
Promise.resolve('hello'),
348+
Promise.resolve('world'),
349+
'static'
350+
];
351+
352+
return client.request('get', 'url', data).then(function() {
353+
assert.deepEqual(serverRequestStub.args[0][2].$data, [
354+
'hello', 'world', 'static'
355+
]);
356+
});
357+
});
328358
});
329359

330360
describe('#respond', function() {
@@ -544,4 +574,4 @@ describe('Client', function() {
544574
assert(resource instanceof Schema.Record);
545575
});
546576
});
547-
});
577+
});

0 commit comments

Comments
 (0)