Terry
Terry

Reputation: 95

AngularJS: Passing Promise, yet Cannot read property 'finally' of undefined

In my angular app, I have 2 methods save() and saveTriggers(). saveTriggers() updates all records by calling a web service (C#). I want to make sure that a block of code is executed after all records are updated in saveTriggers() and control is returned to save(). I believe I need to pass something from the saveTriggers() to make finally block execute. I tried various things, nothing works. Using .then() also gives the same error. I am not that good at JS. Can you please guide me.

           vm.updatedTriggers = []; // IDs are pushed in
           vm.saveTriggers = function () {
                if (vm.updatedTriggers.length === 0) {
                    vm.close();
                } else {
                    vm.saving = true;
                    vm.save()
                        .finally(function () {    // ERROR - Cannot read property 'finally' of undefined
                            console.log("Saved all. Closing...");   // Never REACHES here
                            vm.saving = false;
                            vm.updated = true;
                            $uibModalInstance.close(true);
                    });                            
                }
            };

            vm.save = function () {
                //vm.saving = true;
                for (var i = 0; i < vm.updatedTriggers.length; i++) {
                    var trigger = vm.triggers.find(t => t.id === vm.updatedTriggers[i]);

                    var input = {
                        id: trigger.id,
                        target: trigger.target,
                        targetInfo: vm.targetData,
                        event: trigger.event,
                        eventQuantity: trigger.eventQuantity,
                        eventQuantityExtra: trigger.eventQuantityExtra
                    };

                    rpmService.editDeviceTrigger(input);
                        /*.finally(function () {                                
                            console.log("Updated event");  // Reaches here
                            vm.updated = true;
                            return Promise.resolve(2);                    
                        });*/ // Commenting this also doesn't help
                }
                return Promise.resolve(2);
            };

rpmService.editDeviceTrigger(input)

       public async Task EditDeviceTrigger(EditDeviceTriggerInput input) {
               // calls other methods with await
               // Doesn't return anything
       }

EDIT: Updated Code: I got rid of the error, but the output is not is expected series.

       vm.saveTriggers = function () {
            vm.saving = true;
                   
            vm.save().then
               (function success() {
                    console.log("Returned Result ");
                    console.log("Saved all. Closing...");  // These lines are executed before the event is upated
                    vm.saving = false;                      
                    $uibModalInstance.close(true);
               });
        };

        vm.save = function () {
            var deferred = $q.defer();

            for (var i = 0; i < vm.updatedTriggers.length; i++) {
                var trigger = vm.triggers.find(t => t.id === vm.updatedTriggers[i]);

                var input = {
                    id: trigger.id,
                    ....
                };

                rpmService.editDeviceTrigger(input)
                    .finally(function () {                                
                        console.log("Updated event"); // Successfully updates all events
                        vm.updated = true;
                   });
            }
                                    
            deferred.resolve();
            return deferred.promise;
        };

OUTPUT:

 Returned Result 
 Saved all. Closing...
 Updated event

EXPECTED OUTPUT:

 Updated event
 Returned Result 
 Saved all. Closing...

Thanks.

Upvotes: 0

Views: 240

Answers (1)

Petr Averyanov
Petr Averyanov

Reputation: 9476

Usually you dont need $q.defer-related things, but u can do same using it if u want. Here I guess you just need to collect all your save promises and return new resulting one using $q.all:

vm.save = function () {
    const myAwesomePromises = []

    for (var i = 0; i < vm.updatedTriggers.length; i++) {
        ...

        const savePromise = rpmService.editDeviceTrigger(input);
        savePromise.finally(() => console.log('edit device finally'));// <-- not sure u need this
        myAwesomePromises.push(savePromise);
    }
                            
    return $q.all(myAwesomePromises).finally(() => console.log('All edit device finally'));
};

Upvotes: 1

Related Questions