Learn2Code
Learn2Code

Reputation: 2280

Issue structuring a promise in a loop

I am struggling with getting this resolved, as I am new to Promises.

I need to first read both the Summative and Formative from Firebase before I can determine the StudentPlacement

The way the code below, provides null as the StudentPlacement snapshot.val(), as it is not waiting for the x and y values.

exports.boxScoresUpdate = functions.database.ref('/Tests/{id}/TestScores').onWrite(event => {

    let testScr = 0;

    for (let i = 1; i <= section; i++) {
        //
        testScr += parseInt(nValue[i]);

        var xIndex = 0;
        var yIndex = 0;


        admin.database().ref('TestScores').child(data.key).child('Summative').child(i).once("value").then(x => {

            xIndex = x.val();

        });

        admin.database().ref('TestScores').child(data.key).child('Formative').child(i).once("value").then(y => { 

            yIndex = y.val();

        });

        admin.database().ref('StudentPlacement').child(data.key).child(xIndex + ":" + yIndex).once("value", snapshot => {

            // SnapShot
            console.log("Student Placement is: ", snapshot.val());

        });

    }

}

Can anyone please help me structure the trigger!?

Upvotes: 0

Views: 90

Answers (1)

sketchthat
sketchthat

Reputation: 2688

You're waiting for both functions to finish before executing the next bit of code. Look into Promise.all.

for (let i = 1; i <= section; i++) {
    const xIndexRef = admin.database().ref('TestScores').child(data.key).child('Summative').child(i).once("value");
    const yIndexRef = admin.database().ref('TestScores').child(data.key).child('Formative').child(i).once("value");

    Promise.all([xIndexRef, yIndexRef])
      .then(results => {
        const xSnapshot = results[0];
        const ySnapshot = results[1];

        return admin.database().ref('StudentPlacement').child(data.key).child(xSnapshot.val() + ":" + ySnapshot.val()).once("value");
      })
      .then(snapshot => {
        console.log("Student Placement is: ", snapshot.val());
      });
}

Promise.all waits for both xIndexRef and yIndexRef to complete their execution.

Once executed the results are returned into a thenable object.

You can access the results and complete your execution.

Upvotes: 1

Related Questions