Tengo una aplicación en la que estoy ingresando un nuevo registro en una base de datos con un identificador.

Mi primera declaración es una declaración if que envuelve todo el documento:

if(body['id'] && body['business'] && body['contact_no'] && body['contact_email'] && body['addr_1'] && body['addr_2'] && body['post_code'] && body['gs_unit'] && body['timezone']){

     (everything goes here)
}

La declaración if anterior solo asegura que haya un valor para todo (o que exista).

El siguiente paso es ejecutar una consulta que verifique si algo está registrado con esa identificación:

var sql1 = "SELECT * FROM epas_plc WHERE uid = ?";

conn.query(sql1,[id], function (err1, resp1) {

    console.log(resp1.length);
    var rlength = resp1.length;

    if(resp1.length == 1){
            res.send({'status' : 'error', 'information' : 'id already exsists'});
            return;
    }

});

La consulta anterior funciona y dará la respuesta indicada si hay una coincidencia. La siguiente consulta debe ejecutarse si no hay coincidencia, rlength como se define en la consulta anterior:

if (rlength == 0) {
    var sql = "INSERT INTO epas_plc (uid, business, contact_no, contact_email, addr_1, addr_2, post_code, gs_unit, timezone) VALUES(?,?,?,?,?,?,?,?,?)";

    conn.query(sql,[id, body['business'], body['contact_no'], body['contact_email'], body['addr_1'], body['addr_2'], body['post_code'], body['gs_unit'], body['timezone']], function(error, response){

        if(error) throw error;

        res.send({'status' : 'success', 'information' : 'successfully created entry with id: ' + req.body.id});
    })

}

Desafortunadamente, esto no funciona como Can't set headers after they are sent.

¿Alguien sabe cómo resolver este problema y / o tiene consultas anidadas?

Editar: el módulo SQL es MYSQL

1
N. Sainsbury 14 feb. 2018 a las 19:38

2 respuestas

La mejor respuesta

Puedo ver algunos problemas en su código, como la instrucción return después de send, y cuándo verificar el error. Propongo esta solución:

var sql1 = "SELECT * FROM epas_plc WHERE uid = ?";

conn.query(sql1, [id], function(err1, resp1) {

    console.log(resp1.length);
    var rlength = resp1.length;
    if (err1) res.status(500).send({
        'msg': 'error found'
    });

    if (rlength == 1) {
        res.send({
            'status': 'error',
            'information': 'id already exsists'
        });
    } else {
        var sql = "INSERT INTO epas_plc (uid, business, contact_no, contact_email, addr_1, addr_2, post_code, gs_unit, timezone) VALUES(?,?,?,?,?,?,?,?,?)";

        conn.query(sql, [id, body['business'], body['contact_no'], body['contact_email'], body['addr_1'], body['addr_2'], body['post_code'], body['gs_unit'], body['timezone']], function(error, response) {

            if (error) res.status(500).send({
                'msg': 'error found'
            });

            res.send({
                'status': 'success',
                'information': 'successfully created entry with id: ' + req.body.id
            });
        })
    }

});

Es importante mantener el código claro, no tiene sentido usar var rlength = resp1.length; y luego verificarlo con if(resp1.length == 1){. Cuando se encuentra algún error, puede enviarlo a quien llama porque está en un alcance de solicitud.

1
Lucas Costa 14 feb. 2018 a las 17:03

Creo que el problema que tiene está relacionado con el "alcance" y el "asincrónico".

En primer lugar, alcance:

El problema del 'alcance' aquí es que var rlength = resp1.length; se declara dentro de la función de la primera consulta.

Esto significa que si tiene las dos consultas en línea entre sí, como:

conn.query(sql1,[id], function (err1, resp1) {
    // ... 
    var rlength = resp1.length;
    // ... 
});

// You will find that 'rlength' is not defined
// console.log(typeof rlength);
if (rlength == 0) {
    // ...
}

Esto se resuelve colocando la 'declaración if' dentro de la primera función de consulta así:

conn.query(sql1,[id], function (err1, resp1) {
    // ...
    var rlength = resp1.length;
    // ...
    if (rlength == 0) {
        // ...
    }
});

En segundo lugar, async

Este problema es un poco menos obvio, si el código está estructurado así:

conn.query(sql1,[id], function (err1, resp1) {
    // ...
});

if (rlength == 0) {
    // ...
}

La 'instrucción if' se ejecutará independientemente de si la consulta está completa. Es decir, la "instrucción if" podría ejecutarse antes de la consulta.

0
scagood 14 feb. 2018 a las 16:58