'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