Estoy tratando de agregar nuevos usuarios a la base de datos y tener la identificación iterada automáticamente. La forma en que trato de hacer esto es ejecutar una consulta primero para verificar el número total de filas y luego agregarle 1 para asignarla como la ID del usuario que quiero agregar.

Uno de los problemas que tengo es que en la primera consulta la asignación de newUser.id tiene un alcance de bloque y no puedo acceder a ese valor fuera de él. La identificación para newUser permanece nula o indefinida dependiendo de cómo muevo las cosas

/add user to DB
router.post("/", (req, res) => {

var newID;

const newUser = {
    id: null,
    name: req.body.name,
    email: req.body.email,
    active: true
};

 db.result("SELECT COUNT(*) FROM users")
    .then(data => {
        newID = parseInt(data.rows[0].count) + 1;
        newUser.id = newID;

     //IF I CONSOLE.LOG(newUser) here then the value for id is 14

    });

    //IF I CONSOLE.LOG(newUser) here then the value for id is NULL

  db.none(
    "INSERT INTO users(id, name, email, active) VALUES ($1, $2, $3, $4)",
    [newUser.id, newUser.name, newUser.email, newUser.active]
  )
    .then(data => {
      res.status(200).json({ msg: "new user was added" });
    })
    .catch(error => {
      console.log("ERROR", error);
    });
0
Joon Joonam 24 feb. 2020 a las 00:24

2 respuestas

La mejor respuesta

la asignación de newUser.id tiene un alcance de bloque y no puedo acceder a ese valor fuera de él.

Deberá usar el encadenamiento de promesas para eso:

db.result("SELECT …")
.then(data => {
    newUser.id = parseInt(data.rows[0].count) + 1;
    return db.none("INSERT …", newUser);
}).then(data => {
    res.status(200).json({ msg: "new user was added" });
}, error => {
    console.log("ERROR", error);
});

Estoy tratando de agregar nuevos usuarios a la base de datos y tener la identificación iterada automáticamente

No haga dos consultas para lograr eso. Utilice una columna de identidad o secuencia en la base de datos para eso.

O al menos unir las dos consultas en una sola declaración para ejecutar a la vez:

db.none(
  "INSERT INTO users(id, name, email, active) VALUES ((SELECT COUNT(*)+1 FROM users), $1, $2, $3)",
  [newUser.name, newUser.email, newUser.active]
)
.then(data => {
  res.status(200).json({ msg: "new user was added" });
}, error => {
  console.log("ERROR", error);
});
1
Bergi 23 feb. 2020 a las 21:41

Como está utilizando más de una consulta a la vez, debe usar una tarea:

await db.task('add-new-user', async t => {
    const count = await t.one('SELECT count(*) FROM users', [], a => +a.count);
    newUser.id = count + 1;
    return t.none('INSERT INTO users(${this:name}) VALUES(${this:csv})', newUser);
});

PD Debería usar el tipo serial en su lugar, y luego puede evitar todo esto.

2
vitaly-t 27 feb. 2020 a las 20:35