3

I am using angular resource modul to work with my restfull webserver. For exampe i have a method which returns an array of 10 elements and what i want to do is just save result into some javascript variable (not in angular scope) called books.

So i have written a simple method which 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 that BookFactory.getBooks.query works as expected and truly returns 10 elements. So there is a simple logic inside this function, i just push each element to the array books.

Also i have a test function for testing getBooks() function. Here it is:

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

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

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

works asynchronously and until server request is processing, function getBooks() returns an empty array of books (please correct me if i am wrong).

Here is a question, how can i edit my function, to work it correctly. I want to get data from rest, fill the array books with this data and then return it.

Thanks in advance.

1
  • So you know what asynchronous code is and still "I want to get data from rest, fill the array books with this data and then return it"? Commented Jul 5, 2015 at 8:39

2 Answers 2

2

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

This is the thing. Asynchronous programming is not really compatible with synchronous. So you can't just combine them. However you could work in a synchronous-like way, and this is where promises comes very powerful. You don't return data, you return stateful Promise object instead.

So instead of returning books return a Promise for this books:

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

Then in consuming code you would use this wrapper object with underlying state control mechanism which will proceed when books are loaded and available:

$scope.testGetBooksMethod = function (user_id) {
    getBooks(user_id).then(function(books) {
        alert(books.length);
    });
};
Sign up to request clarification or add additional context in comments.

Comments

1

You need to use promise concept here, testGetBooksMethod of controller function will wait till getBooks of service method will complete its call. For that you need to return the BookFactory.getBooks.query promise from getBooks function. After data gets retrieve the books are will get created & will return from the getBooks method. While calling getBooks method you need to use .then function that will continue the chain promise thing, when data is returned from the getBooks this then function will get the data returned from the 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);
    });
};

4 Comments

@user3127896 oh..Thanks..but why not mine answer..? Just curious to know that.. so that I can improve on this..
i saw your answer second=)
@user3127896 you could check the time actual timestamp by hovering on answered 13 minutes ago .. Its here dsfq 2015-07-05 08:46:12Z and pankajparkar 2015-07-05 08:45:59Z ..Now decide who answered first.
@user3127896 basically I beated him by 13 secs.. I don't want to force you to accept answer..but just showing you the difference in time..As you said you saw my answer later

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.