1
votes

I'm struggling with a problem with saveChanges method.

It seems that saveChanges leaves entity's state as it was before and changes made on server are not reflected on a client because of that. I tried both merge strategies, and the result is the same.

I do initialize manager like that:

var manager = new breeze.EntityManager({ serviceName: serviceUrl });

Then I get all entities I need to work with in parallel calls.

        manager.fetchMetadata()
            .then(function() {
                store.registerEntityTypeCtor("GameGroup", GameGroup);
                store.registerEntityTypeCtor("Game", Game);
                store.registerEntityTypeCtor("LimitGroup", LimitGroup, LimitGroupInitializer);
                store.registerEntityTypeCtor("Limit", Limit, LimitInitializer);

                addValidators();
                subscribeToStateChanges();
            })
            .then(function() {
                return Q.all([
                    getEntitiesByQuery(gamesQuery, model.games),
                    getEntitiesByQuery(gameGroupsQuery, model.gameGroups),
                    getEntitiesByQuery(limitsQuery, model.limits),
                    getEntitiesByQuery(limitGroupsQuery, model.limitGroups)]);
            })
            .then(function() {
                handlers.onSuccess();
            })
            .fail(function () {
                handlers.onFail();
            });

        function getEntitiesByQuery(query, modelProperty) {
            manager.executeQuery(query)
                .then(function (data) {
                    modelProperty(data.results);
                });
        }

But then let's say we want to change some entity's property: Here's a console log:

manager.getEntities('LimitGroup')[0].entityAspect.entityState.name
"Unchanged"
manager.getEntities('LimitGroup')[0].Name('SomeName')
LimitGroup
manager.getEntities('LimitGroup')[0].entityAspect.entityState.name
"Modified"
manager.hasChanges()
true
manager.saveChanges().done();
undefined
manager.getEntities('LimitGroup')[0].entityAspect.entityState.name
"Modified"

As you can see, a state is still 'Modified' after saveChanges call. Changes to the name I made were saved to the database and everything except that seems to be working okay. Same thing happens to 'Added' entities, however, if I call setDeleted method on some entity, it'll be set as 'Detached' immediately after a call and nowhere to be found in a manager's cache.

I looked into some breeze examples and they don't have the same issue, what can be the problem?

Thank you!

Update #1

Here's how saveChanges is called:

        self.showBusy();

        manager.saveChanges()
            .then(function (data) {
                self.hideBusy();
                console.log(manager.getEntities('LimitGroup')[0].entityAspect.entityState.name);
            })
            .fail(saveFailed);

Again, the entity state is shown as 'Modified'

Update #2

So I substituted then() with done() call, and the result is the same.

manager.saveChanges()
            .done(function(data) {
                self.hideBusy();
                console.log(manager.getEntities('LimitGroup')[0].entityAspect.entityState.name);
            });
2
Your .then() is executed before Breeze has saved changes and updated the entities in the cache. You need to use .fin() or .done() as they will wait until everything is completed before processing the code, as shown in my answer.PW Kad

2 Answers

1
votes

The following code is not valid, because you need to pass a function into the done call and then check the entitiesState from that point, once the callback is received.

manager.saveChanges().done(checkStates);

function checkStates() {
    manager.getEntities('LimitGroup')[0].entityAspect.entityState.name
}

This will wait until the saveChanges callback is returned before checking the entityState.

0
votes

The problem was that I didn't mark api controller with BreezeController attribute.