Skip to content

Commit acddf61

Browse files
committed
dataservice.abstractrest makes changeRequestSucceeded available to derived types as _changeRequestSucceeded
See http://stackoverflow.com/questions/24702308/breeze-dataservice-abstractrest-with-sparse-save-response/24769885?noredirect=1#comment40082212_24769885 Affected nuget packages updated
1 parent ef8b1b0 commit acddf61

File tree

4 files changed

+215
-187
lines changed

4 files changed

+215
-187
lines changed

breeze.labs.dataservice.abstractrest.js

+21-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Breeze Labs Abstract REST DataServiceAdapter
33
*
4-
* v.0.6.0
4+
* v.0.6.1
55
*
66
* Extends Breeze with a REST DataService Adapter abstract type
77
*
@@ -77,6 +77,7 @@
7777
_addToSaveContext: _addToSaveContext,
7878
_ajaxImpl: undefined, // see initialize()
7979
_catchNoConnectionError: abstractDsaProto._catchNoConnectionError,
80+
_changeRequestSucceeded: _changeRequestSucceeded,
8081
_createErrorFromResponse: _createErrorFromResponse,
8182
_createChangeRequest: _createChangeRequest,
8283
_createJsonResultsAdapter: _createJsonResultsAdapter,
@@ -322,6 +323,21 @@
322323
}
323324

324325
/*** private members ***/
326+
function addKeyMapping(saveContext, index, saved){
327+
var tempKey = saveContext.tempKeys[index];
328+
if (tempKey) {
329+
// entity had a temporary key; add a temp-to-perm key mapping
330+
var entityType = tempKey.entityType;
331+
var tempValue = tempKey.values[0];
332+
var realKey = getRealKey(entityType, saved);
333+
var keyMapping = {
334+
entityTypeName: entityType.name,
335+
tempValue: tempValue,
336+
realValue: realKey.values[0]
337+
};
338+
saveContext.saveResult.keyMappings.push(keyMapping);
339+
}
340+
}
325341

326342
function createChangeRequests(saveContext, saveBundle) {
327343
var adapter = saveContext.adapter;
@@ -382,7 +398,7 @@
382398
if ((!status) || status >= 400) {
383399
tryRequestFailed(response);
384400
} else {
385-
var savedEntity = changeRequestSucceeded(saveContext, response, index);
401+
var savedEntity = adapter._changeRequestSucceeded(saveContext, response, index);
386402
adapter._processSavedEntity(savedEntity, response, saveContext, index);
387403
deferred.resolve(true);
388404
}
@@ -418,34 +434,20 @@
418434
}
419435
}
420436

421-
function changeRequestSucceeded(saveContext, response, index) {
437+
function _changeRequestSucceeded(saveContext, response, index) {
422438
var saved = saveContext.adapter._getResponseData(response);
423439
if (saved && typeof saved === 'object') {
424440
// Have "saved entity" data; add its type (for JsonResultsAdapter) & KeyMapping
425441
saved.$entityType = saveContext.originalEntities[index].entityType;
426-
addKeyMapping();
442+
addKeyMapping(saveContext, index, saved);
427443
} else {
428444
// No "saved entity" data; return the original entity
429445
saved = saveContext.originalEntities[index];
430446
}
431447
saveContext.saveResult.entities.push(saved);
432448
return saved;
433449

434-
function addKeyMapping(){
435-
var tempKey = saveContext.tempKeys[index];
436-
if (tempKey) {
437-
// entity had a temporary key; add a temp-to-perm key mapping
438-
var entityType = tempKey.entityType;
439-
var tempValue = tempKey.values[0];
440-
var realKey = getRealKey(entityType, saved);
441-
var keyMapping = {
442-
entityTypeName: entityType.name,
443-
tempValue: tempValue,
444-
realValue: realKey.values[0]
445-
};
446-
saveContext.saveResult.keyMappings.push(keyMapping);
447-
}
448-
}
450+
449451
}
450452

451453
}, this));

nuget.builds/Breeze.DataService.SharePoint/Breeze.DataService.SharePoint.nuspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
33
<metadata>
44
<id>Breeze.DataService.SharePoint</id>
5-
<version>0.3.0</version>
5+
<version>0.3.1</version>
66
<title>Breeze Labs: SharePoint 2013 OData DataServiceAdapter</title>
77
<authors>Ward Bell,Andrew Connell</authors>
88
<owners>Ward Bell</owners>

nuget.builds/Breeze.DataService.SharePoint/content/Scripts/breeze.labs.dataservice.abstractrest.js

+64-49
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Breeze Labs Abstract REST DataServiceAdapter
33
*
4-
* v.0.2.5
4+
* v.0.6.1
55
*
66
* Extends Breeze with a REST DataService Adapter abstract type
77
*
@@ -12,7 +12,7 @@
1212
*
1313
* A concrete REST adapter
1414
*
15-
* - MUST replace the _createSaveRequest with a concrete implementation to enable save
15+
* - MUST replace the _createChangeRequest with a concrete implementation to enable save
1616
*
1717
* - SHOULD replace the "noop" JsonResultsAdapter.
1818
*
@@ -56,6 +56,9 @@
5656

5757
breeze.AbstractRestDataServiceAdapter = ctor;
5858

59+
// borrow from the AbstractDataServiceAdapter
60+
var abstractDsaProto = breeze.AbstractDataServiceAdapter.prototype;
61+
5962
ctor.prototype = {
6063

6164
// Breeze DataService API
@@ -65,16 +68,19 @@
6568
saveChanges: saveChanges,
6669

6770
// Configuration API
71+
ChangeRequestInterceptor: abstractDsaProto.changeRequestInterceptor, // default, no-op ctor
6872
checkForRecomposition: checkForRecomposition,
6973
saveOnlyOne: false, // true if may only save one entity at a time.
7074
ignoreDeleteNotFound: true, // true if should ignore a 404 error from a delete
7175

7276
// "protected" members available to derived concrete dataservice adapter types
7377
_addToSaveContext: _addToSaveContext,
7478
_ajaxImpl: undefined, // see initialize()
79+
_catchNoConnectionError: abstractDsaProto._catchNoConnectionError,
80+
_changeRequestSucceeded: _changeRequestSucceeded,
7581
_createErrorFromResponse: _createErrorFromResponse,
82+
_createChangeRequest: _createChangeRequest,
7683
_createJsonResultsAdapter: _createJsonResultsAdapter,
77-
_createSaveRequest: _createSaveRequest,
7884
_clientTypeNameToServer: _clientTypeNameToServer,
7985
_getEntityTypeFromMappingContext: _getEntityTypeFromMappingContext,
8086
_getNodeEntityType: _getNodeEntityType,
@@ -100,9 +106,7 @@
100106
throw new Error("Breeze was unable to find an 'ajax' adapter for " + adapter.name);
101107
}
102108

103-
// Todo: hacking for Q right now; use promise adapter after Breeze makes it available
104-
// if no breeze.Q, assume Q is in global window namespace (e.g., Q.js)
105-
adapter.Q = breeze.Q ? breeze.Q : window.Q;
109+
adapter.Q = breeze.Q; // adapter.Q is for backward compat
106110

107111
if (!adapter.jsonResultsAdapter) {
108112
adapter.jsonResultsAdapter = adapter._createJsonResultsAdapter();
@@ -130,7 +134,7 @@
130134
params: mappingContext.query.parameters,
131135
success: querySuccess,
132136
error: function (response) {
133-
deferred.reject(adapter._createErrorFromResponse(response, url));
137+
deferred.reject(adapter._createErrorFromResponse(response, url, mappingContext));
134138
}
135139
});
136140
return deferred.promise;
@@ -154,18 +158,17 @@
154158
}
155159

156160
function saveChanges(saveContext, saveBundle) {
157-
var adapter = this;
161+
var adapter = saveContext.adapter = this;
158162
var Q = adapter.Q;
159163

160164
try {
161165
if (adapter.saveOnlyOne && saveBundle.entities.length > 1) {
162166
return Q.reject(new Error("Only one entity may be saved at a time."));
163167
}
164-
saveContext.adapter = adapter;
165168
adapter._addToSaveContext(saveContext);
166169

167-
var requests = createSaveRequests(saveContext, saveBundle);
168-
var promises = sendSaveRequests(saveContext, requests);
170+
var requests = createChangeRequests(saveContext, saveBundle);
171+
var promises = sendChangeRequests(saveContext, requests);
169172
var comboPromise = Q.all(promises);
170173
return comboPromise
171174
.then(reviewSaveResult)
@@ -213,13 +216,22 @@
213216
jrAdapter.clientTypeNameToServer(typeName) : typeName;
214217
}
215218

216-
function _createErrorFromResponse(response, url) {
217-
var result = new Error();
218-
result.response = response;
219-
if (url) { result.url = url; }
220-
result.message = response.message || response.error || response.statusText;
221-
result.statusText = response.statusText;
222-
result.status = response.status;
219+
function _createChangeRequest(/* saveContext, entity, index */) {
220+
throw new Error("Need a concrete implementation of _createChangeRequest");
221+
}
222+
223+
// Create error object for both query and save responses.
224+
// 'context' can help differentiate query and save
225+
// 'errorEntity' only defined for save response
226+
function _createErrorFromResponse(response, url, context, errorEntity) {
227+
var err = new Error();
228+
err.response = response;
229+
if (url) { err.url = url; }
230+
err.status = response.status || '???';
231+
err.statusText = response.statusText;
232+
err.message = response.message || response.error || response.statusText;
233+
fn_.catchNoConnectionError(err);
234+
return err;
223235
}
224236

225237
function _createJsonResultsAdapter(/*dataServiceAdapter*/) {
@@ -232,10 +244,6 @@
232244
});
233245
}
234246

235-
function _createSaveRequest(/* saveContext, entity, index */) {
236-
throw new Error("Need a concrete implementation of _createSaveRequest");
237-
}
238-
239247
function _getEntityTypeFromMappingContext(mappingContext) {
240248
var query = mappingContext.query;
241249
if (!query) {return null;}
@@ -281,7 +289,7 @@
281289
return response.data;
282290
}
283291

284-
function _processSavedEntity(/*savedEntity, saveContext, response, index*/){
292+
function _processSavedEntity(/*savedEntity, response, saveContext, index*/){
285293
// Virtual method. Override in concrete adapter if needed.
286294
}
287295

@@ -315,15 +323,35 @@
315323
}
316324

317325
/*** private members ***/
326+
function addKeyMapping(saveContext, index, saved){
327+
var tempKey = saveContext.tempKeys[index];
328+
if (tempKey) {
329+
// entity had a temporary key; add a temp-to-perm key mapping
330+
var entityType = tempKey.entityType;
331+
var tempValue = tempKey.values[0];
332+
var realKey = getRealKey(entityType, saved);
333+
var keyMapping = {
334+
entityTypeName: entityType.name,
335+
tempValue: tempValue,
336+
realValue: realKey.values[0]
337+
};
338+
saveContext.saveResult.keyMappings.push(keyMapping);
339+
}
340+
}
318341

319-
function createSaveRequests(saveContext, saveBundle) {
342+
function createChangeRequests(saveContext, saveBundle) {
320343
var adapter = saveContext.adapter;
321344
var originalEntities = saveContext.originalEntities = saveBundle.entities;
322345
saveContext.tempKeys = [];
323346

347+
var changeRequestInterceptor =
348+
abstractDsaProto._createChangeRequestInterceptor(saveContext, saveBundle);
349+
324350
var requests = originalEntities.map(function (entity, index) {
325-
return adapter._createSaveRequest(saveContext, entity, index);
351+
var request = adapter._createChangeRequest(saveContext, entity, index);
352+
return changeRequestInterceptor.getRequest(request, entity, index);
326353
});
354+
changeRequestInterceptor.done(requests);
327355
return requests;
328356
}
329357

@@ -332,7 +360,7 @@
332360
breeze.DataProperty.getRawValueFromServer);
333361
}
334362

335-
function sendSaveRequests(saveContext, requests) {
363+
function sendChangeRequests(saveContext, requests) {
336364
// Sends each prepared save request and processes the promised results
337365
// returns a single "comboPromise" that waits for the individual promises to complete
338366
// Todo: What happens when there are a gazillion async requests?
@@ -345,11 +373,11 @@
345373
saveContext.saveResult = saveResult;
346374

347375
return requests.map(function (request, index) {
348-
return sendSaveRequest(saveContext, request, index);
376+
return sendChangeRequest(saveContext, request, index);
349377
});
350378
}
351379

352-
function sendSaveRequest(saveContext, request, index) {
380+
function sendChangeRequest(saveContext, request, index) {
353381
var adapter = saveContext.adapter;
354382
var deferred = adapter.Q.defer();
355383
var url = request.requestUri;
@@ -370,8 +398,8 @@
370398
if ((!status) || status >= 400) {
371399
tryRequestFailed(response);
372400
} else {
373-
var savedEntity = saveRequestSucceeded(saveContext, response, index);
374-
adapter._processSavedEntity(savedEntity, saveContext, response, index);
401+
var savedEntity = adapter._changeRequestSucceeded(saveContext, response, index);
402+
adapter._processSavedEntity(savedEntity, response, saveContext, index);
375403
deferred.resolve(true);
376404
}
377405
} catch (e) {
@@ -392,9 +420,10 @@
392420
tryRequestSucceeded(response);
393421
} else {
394422
// Do NOT fail saveChanges at the request level
423+
var errorEntity = saveContext.originalEntities[index];
395424
saveContext.saveResult.entitiesWithErrors.push({
396-
entity: saveContext.originalEntities[index],
397-
error: adapter._createErrorFromResponse(response, url)
425+
entity: errorEntity,
426+
error: adapter._createErrorFromResponse(response, url, saveContext, errorEntity)
398427
});
399428
deferred.resolve(false);
400429
}
@@ -405,34 +434,20 @@
405434
}
406435
}
407436

408-
function saveRequestSucceeded(saveContext, response, index) {
437+
function _changeRequestSucceeded(saveContext, response, index) {
409438
var saved = saveContext.adapter._getResponseData(response);
410439
if (saved && typeof saved === 'object') {
411440
// Have "saved entity" data; add its type (for JsonResultsAdapter) & KeyMapping
412441
saved.$entityType = saveContext.originalEntities[index].entityType;
413-
addKeyMapping();
442+
addKeyMapping(saveContext, index, saved);
414443
} else {
415444
// No "saved entity" data; return the original entity
416445
saved = saveContext.originalEntities[index];
417446
}
418447
saveContext.saveResult.entities.push(saved);
419448
return saved;
420449

421-
function addKeyMapping(){
422-
var tempKey = saveContext.tempKeys[index];
423-
if (tempKey) {
424-
// entity had a temporary key; add a temp-to-perm key mapping
425-
var entityType = tempKey.entityType;
426-
var tempValue = tempKey.values[0];
427-
var realKey = getRealKey(entityType, saved);
428-
var keyMapping = {
429-
entityTypeName: entityType.name,
430-
tempValue: tempValue,
431-
realValue: realKey.values[0]
432-
};
433-
saveContext.saveResult.keyMappings.push(keyMapping);
434-
}
435-
}
450+
436451
}
437452

438453
}, this));

0 commit comments

Comments
 (0)