I have the following typescript TypeORM model:
@Entity()
export class Student extends EntityBase {
@Column({ length: 256 })
public firstName: string
@Column({ length: 256 })
public lastName: string
@Column({ unique: true, length: 256 })
public email: string
@Column()
public isSuspended: boolean
@ManyToMany((type) => Teacher, (teacher) => teacher.students, { cascade: true })
@JoinTable()
public teachers: Teacher[]
constructor(first: string, last: string, email: string, isSuspended?: boolean) {
super();
this.firstName = first;
this.lastName = last;
this.email = email;
this.isSuspended = isSuspended ?? false;
}
}
@Entity()
export class Teacher extends EntityBase {
@Column({ length: 256 })
public firstName: string
@Column({ length: 256 })
public lastName: string
@Column({ unique: true, length: 256 })
public email: string
@ManyToMany((type) => Student, (student) => student.teachers)
public students: Student[]
constructor(first: string, last: string, email: string) {
super();
this.firstName = first;
this.lastName = last;
this.email = email;
}
}
This is what the StudentRepository.AddTeacher
does:
public async AddTeacher (student: Student, teacher: Teacher): Promise<Student | null> {
if (teacher && student) {
try {
student.teachers.push(teacher);
return await this.Update(student);
} catch (e) { console.log(e); }
}
return null;
}
The following code should iterate through the list of students to add to teacher collection but it fails to achieve that:
for (let i of request.Students) {
let s: Student | null = await this._studentRepository.GetByEmail(i.email);
if (s !== null && (t!.students.length === 0 || t!.students.find(ss => ss.email == s.email) == null)) {
this._logger.Log(LogLevels.debug, `Adding student: ${JSON.stringify(s)} to teacher ${JSON.stringify(t)}`);
if (!s.teachers.some(i => i.id === t.id)) {
let student = await this._studentRepository.AddTeacher(s, t);
this._logger.Log(LogLevels.debug, `student: ${JSON.stringify(student)}`);
if (student !== null)
count++;
else {
this._logger.Log(LogLevels.error, `Failed to add student ${s.email} to teacher ${t.email}`);
errors.push(new Error("", `Failed to add student ${s.email} to teacher ${t.email}`));
}
} else {
this._logger.Log(LogLevels.error, `Skip existing Student ${i.email} <-> teacher ${t.email}`);
errors.push(new Error("", `Skip existing Student ${i.email} <-> teacher ${t.email}`));
}
} else if (s === null) {
this._logger.Log(LogLevels.error, `Invalid student ${i.email}`);
errors.push(new Error("", `Invalid student ${i.email}`));
} else {
this._logger.Log(LogLevels.error, `Failed to add student ${i.email} to teacher ${t.email}`);
errors.push(new Error("", `Failed to add student ${i.email} to teacher ${t.email}`));
}
};
Input Post data:
{
"teacher": {
"email": "teacher1@gmail.com"
},
"students":
[
"student1@gmail.com",
"student2@gmail.com"
]
}
Log:
2024-07-07 13:44:38:4438 debug: Adding 2 students to teacher teacher1@gmail.com...
2024-07-07 13:44:38:4438 debug: Adding student: {"id":1,"created":"2024-07-07T05:44:33.716Z","modified":"2024-07-07T05:44:33.716Z","firstName":"One","lastName":"Student","email":"student1@gmail.com","isSuspended":false,"teachers":[]} to teacher {"id":1,"created":"2024-07-07T05:44:33.736Z","modified":"2024-07-07T05:44:33.736Z","firstName":"One","lastName":"Teacher","email":"teacher1@gmail.com","students":[]}
2024-07-07 13:44:38:4438 debug: student: {"id":1,"created":"2024-07-07T05:44:33.716Z","modified":"2024-07-07T05:44:33.716Z","firstName":"One","lastName":"Student","email":"student1@gmail.com","isSuspended":false,"teachers":[{"id":1,"created":"2024-07-07T05:44:33.736Z","modified":"2024-07-07T05:44:33.736Z","firstName":"One","lastName":"Teacher","email":"teacher1@gmail.com","students":[]}]}
2024-07-07 13:44:38:4438 debug: Adding student: {"id":2,"created":"2024-07-07T05:44:33.731Z","modified":"2024-07-07T05:44:33.731Z","firstName":"Two","lastName":"Student","email":"student2@gmail.com","isSuspended":false,"teachers":[]} to teacher {"id":1,"created":"2024-07-07T05:44:33.736Z","modified":"2024-07-07T05:44:33.736Z","firstName":"One","lastName":"Teacher","email":"teacher1@gmail.com","students":[]}
2024-07-07 13:44:38:4438 debug: student: {"id":2,"created":"2024-07-07T05:44:33.731Z","modified":"2024-07-07T05:44:33.731Z","firstName":"Two","lastName":"Student","email":"student2@gmail.com","isSuspended":false,"teachers":[{"id":1,"created":"2024-07-07T05:44:33.736Z","modified":"2024-07-07T05:44:33.736Z","firstName":"One","lastName":"Teacher","email":"teacher1@gmail.com","students":[]}]}
I check the database, it seems that the later data (student2
) overrides the previous relation (student1
) instead of adding a new relation.
Code issue. Refactor it to load both entities in the loop solve the problem.