'Why the data appears on mutation, but does not appear on query?

I have students and they can enroll on different courses. When I create a new student, I have courses ids (array) as an argument to get the course information by the id. I am passing the information to the student courses array. The problem is that when I run the mutation, the new created student has courses data (shown in the picture below): enter image description here

But when I call the students query to see all the students, it gives an empty array for the courses of the newly created data. enter image description here

I used console.log() to check the data before and after the line -> await newStudent.save();. Before calling save it is an empty array, but after calling it the course appears. What is the reason for that?

Students entity:

@ObjectType()
export class Student {
    @Field()
    readonly _id: ObjectId;

    @Field()
    @Prop({ required: true })
    name: string;

    @Field()
    @Prop({ required: true, unique: true })
    email: string;

    @Field()
    @Prop({ required: true })
    password: string;

    @Field()
    @Prop({ required: true, unique: true })
    facultyNumber: number;

    @Field()
    @Prop({ default: Date.now() })
    lastLogin?: number;

    @Field(type => [Course], {nullable: true})
    @Prop({default: []})
    courses?: Course[]

}

Courses entity:

@ObjectType()
export class Course {
  @Field()
  readonly _id: ObjectId;

  @Field()
  @Prop({ required: true })
  title: string;

  @Field()
  @Prop({ required: true })
  description: string;

  @Field()
  @Prop({ required: true })
  subject: string;

  @Field()
  @Prop({ required: true })
  credits: number;

  @Field()
  @Prop({ required: true })
  tutor: string;

}

export const CourseModel = getModelForClass(Course);

Students resolver:

@Resolver()
export class StudentResolver {
    @Query(returns => Student)
    async student(@Arg("_id") _id: string): Promise<Student> {
        return await StudentModel.findById(_id);
    }

    @Query(returns => [Student])
    async students(): Promise<Student[]> {
        return await StudentModel.find({});
    }

    @Mutation(returns => Student)
    async createStudent(@Arg("data") data: StudentInput): Promise<Student> {
        const a: CourseResolver = new CourseResolver();

        const studentData = { ...data, password: bcryptjs.hashSync(data.password, 5) }
        const newStudent = new StudentModel(studentData);
        if(newStudent.courses == undefined){
            newStudent.courses = [];
        }
        data.coursesIDs.map((id) => {
            a.course(id).then((res) => {
                newStudent.courses.push(res);
            });
        });
        console.log("before saving courses", newStudent)
        await newStudent.save();
        console.log("after saving coures", newStudent)
        return newStudent;
    }
}

Course Resolver:

@Resolver()
export class CourseResolver {
    @Query(returns => Course)
    async course(@Arg("_id") _id: string): Promise<Course> {
        return await CourseModel.findById(_id);
    }
}

Students arguments:

@InputType({ description: "New student data" })
export class StudentInput {

    @Field()
    @MaxLength(50)
    name: string;

    @Field()
    @IsEmail()
    @MaxLength(30)
    email: string;

    @Field()
    @MinLength(6)
    password: string;

    @Field()
    @IsInt()
    @IsPositive()
    @Min(1000000000)
    facultyNumber: number;

    @Field(type => [String], { nullable: true})
    coursesIDs?: string[]
}

Solution:

await Promise.all(data.coursesIDs.map(async(id) => {
            const promise: Promise<Course>  = CourseModel.findById(id).then((res) => { 
                newStudent.courses.push(res); 
                return res;
            });
            await Promise.resolve(promise);
        }));


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source