Search code examples
angulartypescriptormtypeorm

Typeorm save many to many relation with entities already saved


I am new to Typeorm and the last weeks i have been working on a webpage with Angular + typeorm. I have been trying to solve this "problem" by myself and looking into another previously asked questions here in Stackoverflow, but unfortunately I have not achieved anything these days. Ok so my question is. I have two entities, both with a many-to-many relations between then.

@Entity("noticias")
@Unique(["idnoticias"])
export class Noticias extends BaseEntity{

    @PrimaryGeneratedColumn()
    idnoticias: number;

    @Column({type: "text", nullable: true})
    tituloNoticia: string;

    @Column({type: "text", nullable: false})
    contenidoNoticia: string;

    @Column({type: "text", nullable: true})
    usuario: string;

    @Column({type: "date", nullable: false})
    fechaCreacion: Date;

    @Column({type: "date", nullable: true})
    fechaPublicacion: Date;

    @ManyToMany(type => Etiquetas, etiqueta => etiqueta.noticias)
    @JoinTable()
    etiquetas: Etiquetas[];


}
@Entity("etiquetas")
@Unique(['idetiquetas'])
export class Etiquetas extends BaseEntity {
    
    @PrimaryGeneratedColumn()
    idetiquetas: number;

    @Column({type: "text", nullable: false})
    nombre: string;

    @ManyToMany(type => Noticias, noticia => noticia.etiquetas)
    @JoinTable()
    noticias: Noticias[];
}

I also have a post function, which it receives a 'Noticias' entity and saved it into the DB.

static postNoticia = async (req: Request, res: Response)=>{
        try {
            const {
                tituloNoticia,
                contenidoNoticia,
                usuario,
                fechaCreacion,
                fechaPublicacion,
                etiquetas
            } = req.body;
            
            const noticia = Noticias.create({
                tituloNoticia: tituloNoticia,
                contenidoNoticia: contenidoNoticia,
                usuario: usuario,
                fechaCreacion: fechaCreacion,
                fechaPublicacion: fechaPublicacion,
                etiquetas: etiquetas,
            });
            await noticia.save();
            return res.json(noticia);
        } catch(e) {
            console.log(e);
            res.status(500).json({message: 'Error'});
        }
        
    };

All I want is that, when this 'postNoticia' function receives a request with an array of 'Etiquetas' object, instead of saving all objects again in the DB, if exists, just load then and instantiate the many-to-many relation whith the new 'Noticias' object that I want to save to avoid duplicate objects. At first I tried the cascades, but the problem is that it just insert all again every 'Etiquetas' object. And the purpose is that, if the object exists, just make the relation with its id, not insert it again. I read the official docs, but the example shown there does not clarify this. At least to me. It must be looking first for already in db objects and getting their id, and then make the relation, but no matter how hard I try, I can't get it to work. Sorry if this is already answered somewhere, if so, i will close this. Thank you so very much in advance.


Solution

  • I finally managed to do what I wanted, just fetching the data if already exist previously, and if not, creating it. Then saving again the Noticia object.

    static postNoticia = async (req: Request, res: Response)=>{
        try {
            const {
                tituloNoticia,
                contenidoNoticia,
                usuario,
                fechaCreacion,
                fechaPublicacion,
                etiquetas
            } = req.body;
            
            const noticia = Noticias.create({
                tituloNoticia: tituloNoticia,
                contenidoNoticia: contenidoNoticia,
                usuario: usuario,
                fechaCreacion: fechaCreacion,
                fechaPublicacion: fechaPublicacion,
                etiquetas: etiquetas,
            });
            await noticia.save();
           
            let etiquetasTotales: Etiquetas[] = [];
            for (let i = 0; i < etiquetas.length; i++) {
                console.log(etiquetas[i].nombre);
                const aux = await Etiquetas.findOne({nombre: etiquetas[i].nombre}); 
                if(aux==null) { //si es una etiqueta nueva que no se encuentra en BD
                    let e1 = Etiquetas.create();
                    e1.nombre = etiquetas[i].nombre;
                    await e1.save();
                    etiquetasTotales.push(e1);
                }else{
                    etiquetasTotales.push(aux);
                }
            }
            noticia.etiquetas = etiquetasTotales;
            await noticia.save();
            
            return res.json(noticia);
        } catch(e) {
            console.log(e);
            res.status(500).json({message: 'Error'});
        }
        
    };