0

I am working with an Angular controller that will add an undetermined amount of questions from one or more surveys uploaded to the server to an existing survey(s) with same name, that's just for understanding, the uploading, handling in back-end and returning response works flawlessly, the real problem here is the specific part of just uploading the new questions, which has the following functions:

//Will save next question
const next_question = function (response, this_survey, response_survey, sur_questions, question) {
    deferred = $q.defer();

    new_question = new QuestionsService();

    //Does a bunch of stuff with question object using all those arguments,
    //which is not relevant here

    if (check_existing_question(new_question, sur_questions)) {
        deferred.resolve();
    }
    else {
        new_question.$save({
            actsern: new_question.actsern
        }).then(function () {
            deferred.resolve();
        }).catch(function () {
            deferred.reject();
        });
    }

    return deferred.promise;

};

// Save the questions synchronously (wait for a promise to resolve/reject before saving next question)
async function save_question(response, this_survey, response_survey, sur_questions) {
    // I want to store all promises in an array and return for future error handling
    promises = [];
    for (const quest in response_survey) {
        // promise is undefined in console.log!!
        promise = await next_question(response, this_survey, response_survey, sur_questions, quest);
        console.log(promise);
        //Commented because if not returns error "promises.push is not a function"
        //promises.push(promise);
    }
    //Still undefined
    console.log(promise);
    return promise;
    //The above is how I managed to make it work but what I really want is:
    //return promises;
}

const set_survey_questions = function(response, this_survey, response_survey){

    //Never mind this, unrelated to my problem
    let sur_questions = QuestionsService.get({
        //this_survey is survey object that is being uploaded to, questions and surveys are linked through actsern
        actsern: this_survey.actsern
    });

    sur_questions.$promise.then(function () {

        promises = save_question(response, this_survey, response_survey, sur_questions);

        $q.all(promises).then(function () {
            console.log("Uploaded successfully all questions");
        }).catch(function (reason) {
            console.log(reason);
        });
    });
};

The thing is that I have to save the questions synchronously, wait for one to resolve/reject before saving the next, which is why I am using an async loop function. Everything works fine, the questions are uploaded one after the order, everything goes to the server exactly as it's supposed to. The problem is that I would like to get the promises of next_question() from the async function to deal with their errors in the future and do some other stuff after they all have been resolved using the $q.all(), but the problem is that as far as I know the await should return a promise but it just returns undefined and keeps as undefined even after the loop has finished and all promises, supposedly, resolve.

I know the function next_question() works fine because if it is called directly (outside of async function, directly from set_survey_questions()) it saves the question and returns the promise just as it's supposed.

I'm not very experienced with angular or even javascript for that matter so any help or improvement you can think of is welcome.

6
  • Try declaring your variables: const promises = [] and const promise = await .... Commented Mar 26, 2018 at 19:45
  • Avoid the deferred antipattern! Commented Mar 26, 2018 at 19:46
  • Don't return an array of promises. Call the $q.all right away! Commented Mar 26, 2018 at 19:47
  • Yeah nevermind! Commented Mar 26, 2018 at 19:48
  • @Bergi If I understood correctly you're pointing just an improvement and thanks for the tip, but the problem remains that the await is not returning any promise at all, it doesn't matter if I put in an array and return or just call $q.all() inside the function itself. Commented Mar 26, 2018 at 19:51

1 Answer 1

1

As far as I know the await should return a promise but it just returns undefined

No. You should pass a promise to the await operator, it will then block execution of the async function until the promise is settled and return the result value of the promise.

The problem is that I would like to get the promises of next_question() from the async function to deal with their errors in the future

That doesn't seem to be compatible with your requirement of sequential saving. There are no multiple promises, there's only one active at a time. If any of them errors, the await will throw an exception and your loop will stop.

I think you really should simplify to

async function set_survey_questions(response, this_survey, response_survey) {
    let sur_questions = QuestionsService.get({
        actsern: this_survey.actsern
    });

    await sur_questions.$promise;
    try {
        for (const quest in response_survey) {
            await next_question(response, this_survey, response_survey, sur_questions, quest);
        }
        console.log("Uploaded successfully all questions");
    } catch (reason) {
        console.log(reason);
    }
}
Sign up to request clarification or add additional context in comments.

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.