Angular js combines asynchronous and synchronous code

I am using angular module resource

to work with my restfull webserver. For example, I have a method that returns an array of 10 elements, and what I want to do is just store the result in some javascript variable ( not in angular scope ) called books

.

So, I wrote a simple method that looks like this:

function getBooks(user_id) {
    var books = [];
    BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
        angular.forEach(result, function(i) {
            books.push(i);
        });
    });
    return books;
}

      

Let's assume BookFactory.getBooks.query works as expected and actually returns 10 items. So there is some simple logic inside this function, I just push each item onto the books array .

Also I have a test function to test the function getBooks()

. Here he is:

$scope.testGetBooksMethod = function (user_id) {
    var resut = getBooks(user_id);
    alert(resut.length);
};

      

The result in the notification will always be 0. I know that this part of the code:

BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
            angular.forEach(result, function(i) {
                books.push(i);
            });
        });

      

works asynchronously and while the server request is not being processed, the function getBooks()

returns an empty array of books (please correct me if I'm wrong).

Here is the question, how can I edit my function to work correctly. I want to get data from rest, fill an array with books

this data and then return it.

Thanks in advance.

+3


source to share


2 answers


Here you need to use the concept of promise, testGetBooksMethod

the controller function will wait until getBooks

the service method completes its call. To do this, you need to return a promise BookFactory.getBooks.query

from the function getBooks

. After receiving the data, books will be created and will be returned from the method getBooks

. When calling the method, getBooks

you need to use a function .then

that will continue to work with chaining promises, when data is returned from getBooks

, then the function will receive the data returned from your service.

function getBooks(user_id) {
    var books = [];
    return BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
        angular.forEach(result, function(i) {
            books.push(i);
        });
        return books;
    });
}

      



controller

$scope.testGetBooksMethod = function (user_id) {
    getBooks(user_id).then(function(resut){
        alert(resut.length);
    });
};

      

+1


source


I want to get data from rest, fill books of arrays with this data and then return it.

That's what. Asynchronous programming is actually incompatible with synchronous programming. Therefore, you cannot simply combine them. You can work in sync, however, and this is where promises get very powerful. You don't return data

, instead you return the state of the Promise object .

So instead of returning, books

return the promise for these books:



function getBooks(user_id) {
    return BookFactory.getBooks.query({ id: user_id }).$promise;
}

      

Then, in the consuming code, you should use this wrapper object with a basic stateful mechanism that will take effect when the books are loaded and available:

$scope.testGetBooksMethod = function (user_id) {
    getBooks(user_id).then(function(books) {
        alert(books.length);
    });
};

      

+2


source







All Articles