1

I know similar questions have been asked before but none of the examples make sense to me. (Any I have found have failed to explain the basics for me with the clarity I need.)

I have four AngularJS functions. Each calls a REST service and does stuff that is unrelated to any of the other functions. E.g.

$scope.step1 = function() { $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
}).success(function (data, status, headers, config) {
    $scope.step1data = data;
}).error(function (data, status, headers, config) {  
    $scope.logError(data);
});};

I would like to call the four functions in sequence

  1. $scope.step1
  2. $scope.step2
  3. $scope.step3
  4. $scope.step4

And catch any errors encountered.

I have narrowed the code to the below but it does not work for me. Any help would be greatly appreciated.

$scope.step1().then(function() {
    $scope.step2();
}).then(function() {
    $scope.step3();
}).then(function() {
    $scope.step4();
}).catch(function(e) {
    console.log(e);
});

4 Answers 4

2

You need to return the promise from each step function to your then() callback so that its resulting promise waits for that promise:

$scope.step1().then(function() {
    return $scope.step2();
})...
Sign up to request clarification or add additional context in comments.

Comments

1

First, change your step1, step2, step3 and step4 to return promises like below:

    $scope.step1 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

    $scope.step2 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

    $scope.step3 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

    $scope.step4 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

Then, chain them together like this:

$scope.step1().then(function (step1data) {
  $scope.step1data = step1data;
  $scope.step2().then(function (step2Data) {
    $scope.step2Data = step2Data;
       $scope.step3().then(function (step3Data) {
         $scope.step3Data = step3Data;
         $scope.step4().then(function (step4Data) {
            $scope.step4Data = step4Data;
         });
       });
  });
})

Comments

1

You can mix asynchronous functions with any kind of logic that JavaScript offers if you execute your code synchronously via nsynjs. Here is how your code may need to be transformed:

Step 1: Wrap asynchronous function into generic nsynjs-aware wrapper:

// generic function to retrieve url
// ctx is a reference to caller pseudo-thread context
var httpUrl = function(ctx,url,$http) {
    var res={};
    $http({  
        method: 'GET',  
        url: url,  
        cache: true,
        headers: { "Accept": "application/jsonp;odata=verbose" }
    })
    .success(function (data, status, headers, config) {
        res.data = data;
        ctx.resume() // tells nsynjs to resume caller function
    }).error(function (data, status, headers, config) {
        ctx.resume(data) // resume caller function with exception
        // or replace with these 2 lines if you don't want exception
        // res.error = data;
        // ctx.resume()
    });
    return res;
};
getUrl.nsynjsHasCallback = true; // this tells nsynjs engine that it
                                // should pause execution and wait until ctx.resume() is called from callback

Step 2. Write your logic as if it was synchronous, and put it into function:

function synchronousCode(param1, param2) {
    var step1 = function() {
        var data = httpUrl(nsynjsCtx,"nsynjs/examples/data/file1.json").data;
        console.log("data is ready at this point:",data);
        // do staff this data
        return data;
    };
    var step2 = function() {
        var data = httpUrl(nsynjsCtx,"nsynjs/examples/data/file2.json").data;
        console.log("data is ready at this point:",data);
        // do staff this data
        return data;
    };

    console.log( step1(param1) + step2(param2) ); // do more staff with data
}

Step 3. Run your synchronous code via nsynjs:

nsynjs.run(synchronousCode,{},"value for param1","value for param1",function(){
    console.log("Synchronous Code done");
})

More examples here: https://github.com/amaksr/nsynjs/tree/master/examples

Comments

0

You need to use promise, in your controller, you should inject $q which will handle promise.

 angularApp.controller('YourController', ['$q', '$scope',
    function ($q, $scope) {

        $scope.firstFunction = function () {
            var deferred = $q.defer();
            //Do things you want here...

            console.log(1);

            deferred.resolve();
            return deferred.promise;
        };

        $scope.secondFunction = function () {
            var deferred = $q.defer();
            //Do things you want here...

            console.log(2);

            deferred.resolve();
            return deferred.promise;
        };

        $scope.firstFunction().then(function () {
            $scope.secondFunction.then(function () {
                console.log(3)
            })
        })
    }]);

console logs in functions above will print out:

1
2
3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.