AngularJS throws exception when trying to saveChanges with breeze

梦想与她 提交于 2019-12-11 17:40:00

问题


I'm new to AngularJS and Breeze. I'm trying to save changes and have a problem with that. Here's my code:

In controller:

function update() {
        vm.loading = true;
        return datacontext.saveSettings().then(function () {
            vm.loading = false; // never gets called
        }).fail(function (data) {
            vm.loading = false; // never gets called
        });
    }

In datacontext:

 function saveSettings() {
        if (manager.hasChanges()) {
            manager.saveChanges() // breaks here if there are changes
                .then(saveSucceeded)
                .fail(saveFailed)
                .catch(saveFailed);
        } else {
            log("Nothing to save");
            return false;
        };
    }

The error is thrown in angular.js and it's very unhelpful TypeError: undefined is not a function I guess there is something simple I'm missing here, but can't figure out what is it.

Want to note that it does send correct data to SaveChanges method on server, but the error is thrown before any response from the server received. After the response is received it throws another error TypeError: Cannot read property 'map' of undefined but it might be related to the fact the response I return is invalid. I haven't got to that part yet.

Can anyone anyone help with it? I'm lost here.

UPDATE

Here is how I construct my dataservice and manager:

var serviceName = "http://admin.localhost:33333/api/breeze/"; // 
var ds = new breeze.DataService({
    serviceName: serviceName,
    hasServerMetadata: false,
    useJsonp: true,
    jsonResultsAdapter: jsonResultsAdapter
});
var manager = new breeze.EntityManager({ dataService: ds });
model.initialize(manager.metadataStore);

回答1:


Two problems:

  1. Your datacontext method does not return a promise so the caller cannot find anything to hang the then or fail call on.

  2. You should be callingcatch, not fail

1. Return a promise

Your saveSettings method did not return a result in the success case so it must fail. Your method must also return a promise in the fail case ... or it will also fail.

And while I'm here, since there is no real difference between your success and fail case, you might as well move the vm.loading toggle to the finally clause.

Try this instead:

function update() {
    vm.loading = true;
    return datacontext.saveSettings()
        .then(function () {
            // .. success handling if you have any
        })
        .catch(function (data) {
            // .. fail handling if you have any
        })
        .finally(funtion() {
            vm.loading = false; // turn it off regardless
        });
}

And now the dataContext ... notice the two return statements return a promise.

function saveSettings() {
    if (manager.hasChanges()) {
        return manager.saveChanges() 
            .then(saveSucceeded)
            .catch(saveFailed);
    } else {
        log("Nothing to save");
        // WHY ARE YOU FAILING WHEN THERE IS NOTHING TO SAVE? 
        // Breeze will handle this gracefully without your help
        return breeze.Q.reject(new Error('Nothing to save'));
    };
}

2. Use catch

I assume you have configured Breeze to use Angular's $q for promises (you should be using the "breeze.angular" service and have injected "breeze" somewhere).

$q does not have a fail method! The equivalent is catch. For some reason you have both attached to your query. You'll get the ReferenceError exception immediately, before the server has a chance to respond ... although it will launch the request and you will get a callback from the server too.

Try just:

return manager.saveChanges() 
    .then(saveSucceeded)
    .catch(saveFailed);

You see many Breeze examples that call fail and fin. These are "Q.js" methods; "Q.js" is an alternative promise library - one used by Breeze/KnockOut apps and it was the basis for Angular's $q.

Both "Q.js" and $q support the now-standard catch and finally promise methods. We're slowly migrating our example code to this standard. There is a lot of old fail/finally code around in different venues. It will take time.

Sorry for the confusion.




回答2:


Update savesetting function like below to return Promise.

function saveSettings() {
    if (manager.hasChanges()) {
       return manager.saveChanges(); // return promise

    } else {
        log("Nothing to save");
        return false;
    };
}

Then you can call then and fail in update function like following.

function update() {
    vm.loading = true;
    return datacontext.saveSettings().then(function () {
        vm.loading = false; // never gets called
    }).fail(function (data) {
        vm.loading = false; // never gets called
    });
}


来源:https://stackoverflow.com/questions/28500013/angularjs-throws-exception-when-trying-to-savechanges-with-breeze

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!