'Insert into two nodejs postgresql tables using async await
I am making an API using Express Nodejs with postgresql. I receive an object from UI which I need to register in 2 normalized tables(Turno, Viaje).
Tables:
Turno
CREATE TABLE IF NOT EXISTS public.turno
(
id_turno bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 1000000 CACHE 1 ),
fecha character varying COLLATE pg_catalog."default",
id_sindicato character varying COLLATE pg_catalog."default",
grupo character varying COLLATE pg_catalog."default",
CONSTRAINT turno_pkey PRIMARY KEY (id_turno)
)
Turno
CREATE TABLE IF NOT EXISTS public.viaje
(
id_carnet_conductor bigint,
numero_turno bigint,
estado character varying(50) COLLATE pg_catalog."default",
hora_salida character varying(25) COLLATE pg_catalog."default",
hora_llegada character varying(25) COLLATE pg_catalog."default",
aporte character varying(25) COLLATE pg_catalog."default",
id_viaje bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 1000000 CACHE 1 ),
id_turno bigint,
CONSTRAINT viajes_pkey PRIMARY KEY (id_viaje)
)
API:
Controller:
app.post("/turnos", async (req, res) => {
try {
const nuevoTurno = await ServicioTurnos.crearTurno(req.body);
res.status(201).json(nuevoTurno.rows[0]);
} catch (error) {
res.status(404);
}
});
Service:
async crearTurno(data) {
try {
const turno = await this.repositorio.crearTurno(data);
const viajes = await this.repositorioViaje.crearViajes(data.viajes, turno.rows[0].id_turno);
const resp = await this.repositorio.obtenerTurnoDetalle(turno.rows[0].id_turno);
const resp = Object.assign(turno, viajes);
return resp;
} catch (error) {
console.error(error.message);
return error;
}
}
Repository:
async obtenerTurnoDetalle(data){
const turno =await pool.query(
"SELECT * FROM public.turno INNER JOIN public.viaje ON turno.id_turno = viaje.id_turno WHERE turno.id_turno = $1",
[data]
);
return turno;
}
async crearTurno(data) {
const {
fecha,
id_sindicato,
grupo
} = data;
const nuevo_turno = await pool.query("INSERT INTO public.turno(fecha, id_sindicato, grupo) VALUES ($1, $2, $3) RETURNING *",[fecha,id_sindicato,grupo])
return nuevo_turno;
}
async crearViajes(data, idTurno) {
const nuevos_viajes = await data.map((v)=>{
const {
id_carnet_conductor,
numero_turno,
estado,
hora_salida,
hora_llegada,
aporte
} = v;
const nuevo_viaje = pool.query(
"INSERT INTO public.viaje(id_carnet_conductor, numero_turno, estado, hora_salida, hora_llegada, aporte, id_turno) VALUES ($1, $2, $3, $4, $5, $6, $7)",
[
id_carnet_conductor,
numero_turno,
estado,
hora_salida,
hora_llegada,
aporte,
idTurno
]
);
return nuevo_viaje
})
return nuevos_viajes;
}
UI received object:
{
"fecha": "2022/12/28",
"id_sindicato": "Movima",
"grupo": "Turno Manana",
"viajes":[
{
"id_carnet_conductor": 12345,
"numero_turno": 5,
"estado": "En Scio",
"hora_salida": "10:00",
"hora_llegada": "15:00",
"aporte": "Pagado"
},
{
"id_carnet_conductor": 12345,
"numero_turno": 5,
"estado": "En Mam",
"hora_salida": "10:00",
"hora_llegada": "15:00",
"aporte": "Pagado"
}
]
}
This was a solution that I thought to do, call the functions of the 2 repositories (Turno and Viaje) from the Turno service. Another solution that I thought to do is directly call the Turno Repository from Turno service and perform 2 SQL Insert, something like this:
async crearTurno(data) {
const {
fecha,
id_sindicato,
grupo
} = data;
const nuevo_turno = await pool.query("INSERT INTO public.turno(fecha, id_sindicato, grupo) VALUES ($1, $2, $3) RETURNING *",[fecha,id_sindicato,grupo])
const nuevos_viajes = viajes.map((v)=>{
v['id_turno']=nuevo_turno.rows[0].id_turno;
const {
id_carnet_conductor,
numero_turno,
estado,
hora_salida,
hora_llegada,
aporte,
id_turno
} = v;
const nuevo_viaje = pool.query(
"INSERT INTO public.viaje(id_carnet_conductor, numero_turno, estado, hora_salida, hora_llegada, aporte, id_turno) VALUES ($1, $2, $3, $4, $5, $6, $7)",
[
id_carnet_conductor,
numero_turno,
estado,
hora_salida,
hora_llegada,
aporte,
id_turno
]
);
return nuevo_viaje
})
const finalResult = Object.assign(nuevo_turno,nuevos_viajes);
return nuevo_turno;
}
Currently the solution does not work due to asynchronism errors. In short, I need the most optimal solution to be able to insert into both tables using async functions (Call 2 repositories or double insert into 1 repository). Or maybe a solution to the approach I'm trying to follow.
Thank you!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
