0

In my node app i am using async.series for executing 3 queries its executed very well.. But in my 3rd query execution i have to execute another query based on result of 3rd query its also working fine. But t i executing some logic in the third query so after all gets completed only i have to call callback....

My code:

async.series({
    levels: function(cb) {
        sequelize.query("select country_id, country_name, level0, level1, level2, level3, level4 from levels").success(function(levelsResults) {
            levelsResult = levelsResults;
            cb(null, levelsResult);
        })
    },
    level1: function(cb) {
        sequelize.query("select id_0, name_0, name_1 from xxxxx group by id_0, name_0, name_1").success(function(level1Result) {
            level1result = level1Result;
            cb(null, level1result);
        })
    },
    keys: function(cb) {
        sequelize.query("select id_0 from xxxx group by id_0").success(function(id_0Result) {
            var obj = {};
            for (var i = 0; i < id_0Result.length; i++) {
                sequelize.query("select id_0, value->>'yyyy' as value from xxxx where id_0 = " + id_0Result[i].id_0 + " limit 1").success(function(keyResult) {
                    var keyArray = [];
                    var keysObjectArray = [];
                    id_0 = keyResult[0].id_0;
                    keyResult = keyResult[0].value;
                    keyResult = JSON.parse(keyResult);

                    for (var prop in keyResult) {
                        keyArray.push(prop)
                    }
                    obj["" + id_0 + ""] = keyArray;
                    keysObjectArray.push(obj);
                    cb(null, keysObjectArray);
                    ---.my problem is here cb is called in the 1st iteration of
                    for loop.It should be called after loop finishes

                })
            }
        })
    }
}, function seriesFinal(seriesErr, seriesResults) {
    if (seriesErr) throw new Error("Something bad!");
    onSuccess(JSON.stringify(seriesResults), callback);

});

My result is:

{"levels":[{levsls}],"level1":[{level1}],"keys":[{}]};

but what i am expecting is:

{"levels":[{levsls}],"level1":[{level1}],"keys":[{},{}]};

EDIT:

Simply how can i make the sequlize query to execute for loop and finally have to call the callback

Help me to solve this..Thanks in advance.....

2 Answers 2

1

The "for" loop runs "n" queries which callbacks randomly the "success" function.

You can use a counter to make sure that all your queries called back

sequelize.query("select id_0 from xxxx group by id_0").success(function(id_0Result){
                var obj = {};
                var counter = 0;
                for(var i=0; i<id_0Result.length; i++){
                    sequelize.query("select id_0, value->>'yyyy' as value from xxxx where id_0 = "+id_0Result[i].id_0+" limit 1").success(function(keyResult){
                            var keyArray=[];
                            var keysObjectArray =[];
                            id_0 = keyResult[0].id_0;                                
                            keyResult = keyResult[0].value;
                            keyResult = JSON.parse(keyResult);

                            for (var prop in keyResult){
                                keyArray.push(prop)
                            }                                
                            obj[""+id_0+""] = keyArray;                                
                            keysObjectArray.push(obj);   
                            counter  +=1;
                            if(counter === id_0Result.length )
                            {                             
                               cb(null, keysObjectArray);
                            }

                    })
                }

Note that the order in keysObjectArray is random as are the callbacks.

Hope it helps.

Yoann

Sign up to request clarification or add additional context in comments.

Comments

1

There's more to async than just async.series! You can use async.forEach to do loops, and for your keys function, async.map will do nicely:

keys: function(cb) {                   
    sequelize.query("select id_0 from xxxx group by id_0").success(function(id_0Result){
        var obj = {};
        // Loop over each object in id_0Result, 
        // and transform it into a new array
        async.map(
            id_0Result, 
            function(result, cb) {
                sequelize.query("select id_0, value->>'yyyy' as value from xxxx where id_0 = "+result.id_0+" limit 1").success(function(keyResult){
                    var keyArray=[];
                    id_0 = keyResult[0].id_0;                                
                    keyResult = keyResult[0].value;
                    keyResult = JSON.parse(keyResult);

                    for (var prop in keyResult){
                        keyArray.push(prop)
                    }                                
                    obj[""+id_0+""] = keyArray;
                    // Add this object to the array result for async.map
                    return cb(null, obj);
                })
            }, 
            // Call the callback for async.series with the result of
            // the mapping; effectively cb(null, transformedArray)
            cb
        );
    });
}

1 Comment

Thanks @Scott Gress ..i have 1 more doubt.. i have an object array is it possible to make key value pair by taking id_0 from my object,i think async.map will help me..

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.