1

I have scenario. Where i Want to execute loop after data has been updated in mongodb. Means Like that :

var i = 0;
while (i< 5) {
    attendanceDataModel.update(query, condition).exec(function(error, data) {
        if (error) {
            console.log("Error @ 168 line in app.js File : \n" + err + "\n");
            i++;
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched.");
                i++;
            } else {
                console.log(currEmpId + " : successfully Logged Out ! :-)" + data + "\n");
                updateRecordNumber(currRecordNumber); 
                i++;  //wrong because it increases the value before updating in DB.
            }
        }
    });
}

var updateRecordNumber = function(currRecordNumber) {

    var condition = { deviceLogId: parseInt(currRecordNumber) };

    lastDeviceLogIdModel.update({}, condition).exec(function(error, data) {
        if (error) {
            console.log("Error @ 213 line in app.js File : \n" + err + "\n");
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched." + "\n");
            } else {
                console.log(currRecordNumber + " : DeviceLogId successfully Updated ! :-)");
      // I want to increase value of i here after updation in database
            }
        }
    });
}

Now, I want to increase variable i value after function updateRecordNumber has successfully updated

6 Answers 6

1

Simplest way is change function like var updateRecordNumber = function(currRecordNumber, callback) and then change invocation: updateRecordNumber(currRecordNumber, function(){ i++ });

But I think it's a much better solution to use some control flow approach, e.g. Promises or Async.js

P.S. of course you have to change function's body:

var updateRecordNumber = function(currRecordNumber, callback) {
// all your async stuff
  callback();
}
Sign up to request clarification or add additional context in comments.

6 Comments

@AmulyaKashyap Yes. You should change while loop with recurent function. function foo(i){ if(i==5) return; /*stuff from your loop*/; foo(i+1); /* instead of i++ */ }; foo(0);
But I recomend to use async library from anwer
but can you explain me your code for future reference....especially that part : updateRecordNumber(currRecordNumber, function(){ i++ }); . What is second parameter and how it is working..
@AmulyaKashyap In javascript all async stuff basicly synchronizing by using callback functions. In your case you should add callback parameter to your async function and call it when all async stuff completed. When you invoke such function generally anonymous function passed as callback. It's body contains code that would be executed when callback will called
But when you have many async functions in your code, their syncronization becomes "callback hell". So I recommend you to use Promises or Async.js lib for syncronization. Just take 10 minutes to look over
|
1

Code can be changed to:

var i = 0;

function startUpdation() {

  return attendanceDataModel.update(query, condition).exec(function(error, data) {
    if (error) {
        console.log("Error @ 168 line in app.js File : \n" + err + "\n");
        i++;
        if (i<5) {
            return startUpdation();
        }
        return;
    } else {
        if (data.length <= 0) {
            console.log("No Records Matched.");
            i++;
            if (i<5) {
                return startUpdation();
            }
            return;
        } else {
            console.log(currEmpId + " : successfully Logged Out ! :-)" + data + "\n");
            return updateRecordNumber(currRecordNumber).then(function (err, data){
                i++;
                if (i<5) {
                    return startUpdation();
                }
                return;
            }); 
        }
    }
});
}

function updateRecordNumber (currRecordNumber) {

var condition = { deviceLogId: parseInt(currRecordNumber) };

return lastDeviceLogIdModel.update({}, condition).exec(function(error, data) {
    if (error) {
        console.log("Error @ 213 line in app.js File : \n" + err + "\n");
    } else {
        if (data.length <= 0) {
            console.log("No Records Matched." + "\n");
        } else {
            console.log(currRecordNumber + " : DeviceLogId successfully Updated ! :-)");
        }
    }
});
}

startUpdation();

Please try this solution.

Comments

1

It would be better if you promisify function updateRecordNumber and write the increment call in the then().

2 Comments

can we promisify on node.js part. I mean this a backend code
Sure.You can use bluebird library to promisify. bluebirdjs.com/docs/getting-started.html
0

Your while loop is synchronous and does not factor in that the response to your database operation will return sometimes later. You need to requery after an unsuscessful operation through recursively rescheduling the operation (with an drop out after 5 tries):

function execute(count, callback) {
    if (count == 5) {
        return callback(new Error('meh...'))
    }

    loadSomethingAsync(function(error, result) {
        if (error || !result) {
            return execute(count++, callback)
        }

        callback(null, result)
    })
}

execute(0, function(error, result) {
    if (error) {
        return console.log('after 5 tries still no result or error...')
    }

    console.log('yay, async op has finished!')
})

Comments

0

How about refactoring the loop to itself be part of the callback? Something like this:

var i = 0,

    fna = function (error, data) {
        if (error) {
            console.log("Error @ 168 line in app.js File : \n" + err + "\n");
            fnc(); //i++;
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched.");
                fnc(); //i++;
            } else {
                console.log(currEmpId + " : successfully Logged Out ! :-)" + data + "\n");
                updateRecordNumber(currRecordNumber);
                //i++;  //wrong because it increases the value before updating in DB.
            }
        }
    },

    updateRecordNumber = function (currRecordNumber) {
        var condition = {
            deviceLogId : parseInt(currRecordNumber, 10)
        };

        lastDeviceLogIdModel.update({}, condition).exec(fnb);
    },

    fnb = function (error, data) {
        if (error) {
            console.log("Error @ 213 line in app.js File : \n" + err + "\n");
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched." + "\n");
            } else {
                console.log(currRecordNumber + " : DeviceLogId successfully Updated ! :-)");
                // I want to increase value of i here after updation in database
                fnc();
            }
        }
    },

    fnc = function () {
        i++;

        if (i < 5) {
            attendanceDataModel.update(query, condition).exec(fna);
        }
    };

attendanceDataModel.update(query, condition).exec(fna);

Comments

0

You can use synchronize module in node js .You can see my blog enter link description here

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.