1

So I have collections of Teacher, Classes. to understand my problem its necessary to understand my database. the structure is

const TeacherSchema = new Schema(
  {
    name: {
      type: String,
      required: true
    },
    email: {
      type: String,
      required: true
    },
    role: {
      type: String,
      default: "teacher"
    },
    userid: {
      type: String,
      required: true
    },
    password: {
      type: String,
      required: true
    },
    
    profileImage: { 
      type: String, 
      required: false
    },
    classes: [{
        type:Schema.Types.ObjectId,
        ref:'class'
    }]//1 teacher will have multiple classes
  },
  { timestamps: true }
);

and the class:

const ClassSchema = new Schema(
  {
    subject: {
      type: String,
      required: true
    },
    teacher:[{
      type:Schema.Types.ObjectId,
      ref: 'teacher'
    }],//once class will have only one teacher

  },
  { timestamps: true }
);

What i want to do is, I want to show teacher how many classes he/she has. here is my controller.

exports.getAllClass= async (req, res, next) => {
    let teacherClasses
    try{
      teacherClasses= await Teacher.findById(req.params.id)//teacher database
      arrayOfClass= teacherClasses.classes //getting the class it has array of objectID
      arrayOfClass.forEach(async (classes)=>{
        let classDB =await Class.findById(classes)
        console.log(classDB.subject)// in the console it shows all the classes.
        return res.status(200).json({
          'name':classDB.subject //but here it only shows one class,the first class name
        })

        


      });
    }catch(err){
      console.log(err)
    }
  }

I have tried many thing, but cant reach to a proper solution. Can you tell me what did i do wrong here or is there any better approach? I want to show all the classes in the return. I am new in programming hence assigned in complex task, please help me.

1 Answer 1

2

You are using forEach on the arrayOfClass and within that forEach you return and send the response. So as soon as the first promise is resolved, the response is sent.

One simple way to do this is to use a for .. of loop and await each class-promise inside and keep track of each result. Once that's done you can send the response:

...
const classes = [];

for(const classId of arrayofClass) {
   const classDB = await Class.findById(classId);
   classes.push({ name: classDB.subject });
}

return res.json(classes);

Another way to do this is to use Promise.all() which might be better if you're dealing with a bigger dataset as is processes in parallel whereas the first solution processes in sequence:

...
const classPromises = await Promise.all(arrayofClass.map(classId => Class.findById(classId)));
const result = classPromises.map(classDB => ({
            name: classDB.subject
        }));

return res.json(result);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.