Search code examples
arraystypescripttypeorm

Why is my Many to Many relationship field undefined?


I am trying to create a follower/following system and when I try to append the new user to the following list I get the error Cannot read property 'push' of undefined. This ends up creating 2 separate tables one for users following other users and one for users being followed by other users. Not sure why it's not picking up the field? Any help is appreciated.

import { Length } from "class-validator";
import {
    Column,
    CreateDateColumn,
    Entity,
    JoinTable,
    ManyToMany,
    OneToMany,
    PrimaryColumn,
    RelationCount,
    Unique,
    UpdateDateColumn
} from "typeorm";

export class User {

    @PrimaryColumn()
    public user_id: string;

    @Column()
    public first_name: string;

    @Column()
    public last_name: string;

    @Column()
    public email: string;

    @Column()
    public phone_number: string;

    @Column()
    public username: string;

    @Column()
    @CreateDateColumn()
    public created_on: Date;

    @Column()
    @UpdateDateColumn()
    public updated_at: Date;

    @ManyToMany((type) => User, (user) => user.following)
    @JoinTable()
    public followers: User[];

    @ManyToMany((type) => User, (user) => user.followers)
    @JoinTable()
    public following: User[];

    @RelationCount((user: User) => user.followers)
    public followers_count: number;

    @RelationCount((user: User) => user.following)
    public following_count: number;
}

const { user_id, 
        follow_user_id } = req.
const user_repo = getRepository(User);
const user = await user_repo.findOne({
    where: {user_id}
});
const follow_user = new User();

follow_user.user_id = follow_user_id;
user.following.push(follow_user);
const result = user_repo.save(user);

Error is referring to this line user.following.push(follow_user);

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'push' of undefined

Solution

  • I didn't test ways below, but think one of them should help you.

    1st way. At your User class.

        // Source code omission
        @ManyToMany((type) => User, (user) => user.followers)
        @JoinTable()
        public following: User[] = []; // ★ Added assign
        // Source code omission
    

    2nd way. At your User class.

    export class User {
        // Source code omission
        constructor() { // ★ Added line
            this.following = []; // ★ Added line
        } // ★ Added line
    }
    

    3rd way. At place where you use User class.

    const follow_user = new User();
    
    follow_user.user_id = follow_user_id;
    user.following = []; // ★ Added line
    user.following.push(follow_user);
    const result = user_repo.save(user);
    

    4th way. At place where you use User class.

    const follow_user = new User();
    
    follow_user.user_id = follow_user_id;
    user.following = [follow_user]; // ★ Edited line
    const result = user_repo.save(user);