Make sure to check out this related question for more information.
When performing a query with an expand operation to retrieve related entities, and subsequently deleting one of these expanded entities, how does the breeze cache get updated?
I'm facing a situation where, even after deleting an expanded item as per the solution suggested in the referenced question, querying from the cache still shows the deleted item unless I force a server call.
Below is the current function I'm using to fetch data from the cache if available or from the server if not. I'm explicitly calling this function after deleting an entity.
function _getByIdExpanded(resource, id, expand, forceRefresh) {
var self = this;
// Check if entity exists in cache and is editable
if (!forceRefresh) {
var entity = self.em.getEntityByKey(resource, id);
if (entity && entity.isReadyForEdit) {
if (entity.entityAspect.entityState.isDeleted()) {
entity = null;
}
return self.$q.when(entity); // Return entity from cache
}
}
// Fetch entity from server
return eq.from(resource + 's')
.where('id', '==', id)
.expand(expand)
.using(self.em).execute()
.to$q(succeeded, self._failed);
function succeeded(data) {
var result = data.results;
var entity = result[0];
if (!entity) {
logError('Could not find ' + resource + ' with id: ' + id, null);
return null;
}
entity.isReadyForEdit = true;
return entity; // Return entity fetched from server
}
}
UPDATE:
Upon further testing, it seems that the issue lies within Angular rather than Breeze.
Here are two relevant functions in my controller:
function deleteEntity(entity) {
return bsDialog.deleteDialog(entity.name).then(function () {
datacontext.markDeleted(entity);
save().then(function () {
if (entity.entityType === dboardConfigEntity) {
$location.path('/subscriber/' + subscriberId);
} else { getDboardConfig(true); }
});
});
}
function getDboardConfig(forceRefresh) {
if ($routeParams.newOrExisting === 'new') {
subscriberId = $routeParams.id;
return vm.dboardConfig = datacontext.dboardConfigs.create(subscriberId);
}
return datacontext.dboardConfigs.getByIdExpanded($routeParams.id, forceRefresh)
.then(function (data) {
vm.dboardConfig = data;
subscriberId = vm.dboardConfig.subscriberId;
vm.hideChildren = false;
});
}
The 'getDboardConfig' function essentially calls the abstract repository function (mentioned earlier):
function getByIdExpanded(id, forceRefresh) {
var expand = 'Dims';
return this._getByIdExpanded(entityName, id, expand, forceRefresh);
}
Below are the 'markDeleted' and 'save' functions within my datacontext:
function markDeleted(entity) {
return entity.entityAspect.setDeleted();
}
function save() {
return em.saveChanges()
.to$q(saveSucceeded, saveFailed);
function saveSucceeded(result) {
logSuccess('Successfully saved to the server', result, true);
return result;
}
function saveFailed(error) {
var msg = config.appErrorPrefix + 'Failed to save changes to the server. '
+ breeze.saveErrorMessageService.getErrorMessage(error);
error.message = msg;
logError(msg, error);
throw error;
}
}
Snippet from my markup:
<table>
<thead>
<th>{{dt.name}}</th>
<th></th>
</thead>
<tbody>
<tr data-ng-repeat="d in vm.dboardConfig.dims | filter:{ dimTypeId: dt.id }">
<td>{{d.name}}</td>
<td>
<a href="" data-ng-click="vm.edit(d)">
Edit
</a>
<a href="" data-ng-click="vm.delete(d)">
Delete
</a>
</td>
</tr>
</tbody>
</table>
Despite correctly handling promise resolutions, why do the elements in my table fail to update without manual refreshing?
ANOTHER UPDATE:
Following browser debugging, it seems that although I've marked the child entity for deletion and saved it, upon fetching the updated entity, the deleted child entity remains included but in a detached state, signifying successful deletion by Breeze. Upon reviewing Breeze documentation, the question arises - How can I modify my code so that Angular doesn't bind detached entities? I initially understood that Angular wouldn't display detached entities, yet it appears otherwise...