How to send a res.json () that is inside a for loop, using node (express) and ajax

0

I am working with NodeJS using express with this I have the routes such as POST and GET I connect to bd and make queries in the < strong> app , but I have a question about the following code:

    function getAllDatabases() {
        return new Promise(function (resolve, reject) {
            connection.query("SHOW DATABASES;", function (err, result) {
                // console.log(result);
                if (err) {
                    return reject(err);
                }

                resolve(result);
            });
        });
    } 

    var data = [];
    function getDataConfig(data_array, res) {

        console.log(data_array);

        return new Promise(function (resolve, reject) {
            for (let i = 0; i < data_array.length; i++) {
                connection.query("SELECT * FROM " + data_array[i].Database + ".config ", function (err, result) {
                    if (err) {
                        return reject(err);
                    }

                    resolve(res.json(result));
                });
            }
        });
    }

router.post('/add_config', function (req, res) {
    var databases = [];
    var data = {
        Dg: req.body.Dg,
        Source: req.body.Source.toLowerCase(),
        Label_1: req.body.Label_1,
        Label_2: req.body.Label_2,
        Label_3: req.body.Label_3,
        Styles: req.body.Styles,
        Method: req.body.Method,
        Intervals: req.body.Intervals,
        allow: req.body.Allow,
        smart: req.body.Smart,
        units: req.body.Units,
        resolution: req.body.Resolution
    }
    getAllDatabases().then(resp => getDataConfig(resp, res));

});

I want to know how to send the res.json (result); that is within the second resolve () in the function getDataConfig , when I send it of that json , I get the following error

  

Error: Can not set headers after they are sent.

the reason I know it because being the res.json within a loop sends the answer and ends immediately that res.json works as if it were a return , it gives the value and ends, Is there any way to solve this problem? thanks

    
asked by CRISTIAN ANDRES VARGAS GONZALE 21.12.2017 в 15:20
source

1 answer

0

You are iterating over an array and in each loop calling res.json that sends the response. You can not call res.json several times because the first one already sends the headers and gives the request for finished.

If you are using the native promises library, what you can do is return an object with the output of all the answers.

function getDataConfig(data_array, res) {

    console.log(data_array);
    var promise_array=[],
        results_object={};

    for (let i = 0; i < data_array.length; i++) {
        let promise = new Promise(function (resolve, reject) {
            connection.query("SELECT * FROM " + data_array[i].Database + ".config ", function (err, result) {
                results_object[data_array[i].Database]=err? err.message : result;
                resolve();
            });

       });
       promise_array.push(promise);
    }
    return Promise.all(promise_array).then(()=>{
         return res.json(results_object);
    });
}

If you notice, I am solving all the promises. But in results_object the value of the key data_array[i].Database can be the result set or the error message.

Rejecting the promise when there is an error would cause Promise.all to never resolve to fail one of the queries.

If you were using an improved library of promises like bluebird you could use convenience methods like Promise.reduce or Promise.each and you could also promote connection.query to treat it as a promise:

const Promise=require('bluebird);

And then:

function getDataConfig(data_array, res) {

    console.log(data_array);
    var promise_array=[],
        results_object={},
        queryAsync = Promise.promisify(connection.query);

    for (let i = 0; i < data_array.length; i++) {
        let promise = queryAsync("SELECT * FROM " + data_array[i].Database + ".config ")
          .then((result)=> {
             results_object[data_array[i].Database]=result;
             return;
          }).catch((err)=>{
             results_object[data_array[i].Database]=err.message;
             return;
          }); 

       });
       promise_array.push(promise);
    }
    return Promise.all(promise_array).then(()=>{
         return res.json(results_object);
    });
}
    
answered by 22.12.2017 в 15:11