Home > front end >  Res.send() returning empty array
Res.send() returning empty array

Time:10-25

I'm trying to make an API call but the customizeObj is empty in last then.

userRouter.get("/getusers", (req, apiRes) => {
  let users;
  var customizeObj = [];
  User.find()
    .then((res) => {
      users = res;
    })
    .then(() => {
      users.forEach(async (user) => {
        let event = null;
        event = await Event.findById(user.eventID);
        let year = event.date.getFullYear();
        let month =
          event.date.getMonth()   1 < 10
            ? "0"   event.date.getMonth()   1
            : event.date.getMonth()   1;
        let day =
          event.date.getDate() < 10
            ? "0"   event.date.getDate()
            : event.date.getDate();

        customizeObj.push({
          firstName: user.firstName,
          lastName: user.lastName,
          phoneNumber: user.phoneNumber,
          zipCode: user.zipCode,
          type: event.type,
          location: event.location,
          date: new Date(`${year}-${month}-${day}`),
        });
        console.log(customizeObj); // Not empty
      });
      console.log(customizeObj); // Empty
    })
    .then(() => {
      console.log(customizeObj); // Empty
      apiRes.send(customizeObj) // Sends emprty array
    })
    .catch((err) => console.log(err));
});

can please anyone help me with that? I don't know why it's empty

CodePudding user response:

Based on express and mongoose - this should work as per the above details provided.

userRouter.get("/getusers", (req, res) => {
  try{
    let customizeObj = [];
    //get users and lean
    const users = await User.find().lean();
    if(!users.length){
      //should return empty if users don't exist.
      return res.send(customizeObj); 
    }
    //loop over users.
    for(let i = 0 ; i < users.length ; i  ){
      //get event of user by users[i].eventID.
      let event = await Event.findById(users[i].eventID).lean();
      //if event exists you create the customized object, if doesn't exist again no element will be pushed to customizeObj array.
      if(event){
        let year = event.date.getFullYear();
        let month =
        event.date.getMonth()   1 < 10
          ? "0"   event.date.getMonth()   1
          : event.date.getMonth()   1;
        let day =
        event.date.getDate() < 10
          ? "0"   event.date.getDate()
          : event.date.getDate();
        customizeObj.push({
            firstName: users[i].firstName,
            lastName: users[i].lastName,
            phoneNumber: users[i].phoneNumber,
            zipCode: users[i].zipCode,
            type: event.type,
            location: event.location,
            date: new Date(`${year}-${month}-${day}`),
          });
      }
    }
    res.send(customizeObj);
  } catch(error){
    console.log('error in api',error);
    res.status(500).send({message: 'unknown error', error});
  }
});

Also, you should be creating a ref to events model and use populate('event') to get events in a single query instead of querying in a loop.

CodePudding user response:

The reason for customizeObj to be empty is probably the fact that it hasn't been filled yet. The second .then function where you iterate over users does not return a promise so the next then is executed immediately, it does not wait for the forEach loop to finish.

I have simplyfied your code to only use async await instead of mixing it with Promises(.then)

I believe it's much easier to read and the code should be self explanatory.

userRouter.get("/getusers", async (req, res) => {
    let users;
    let customizeObj = [];

    try {
        // use exec for a better stack trace
        let users = User.find({}, 'eventID').exec();
        // get all events in a single query
        let events = await Event.find({ _id: { $in: users.map(u => u.eventID) }}).exec();

        users.forEach((user) => {
            let event = events.find(ev => ev._id === user.eventID);
            let year = event.date.getFullYear();
            let month = event.date.getMonth()   1 < 10 ? "0"   event.date.getMonth()   1 : event.date.getMonth()   1;
            let day = event.date.getDate() < 10 ? "0"   event.date.getDate() : event.date.getDate();

            customizeObj.push({
                firstName: user.firstName,
                lastName: user.lastName,
                phoneNumber: user.phoneNumber,
                zipCode: user.zipCode,
                type: event.type,
                location: event.location,
                date: new Date(`${year}-${month}-${day}`),
            });
        });

        res.json(customizeObj);
    } catch(e){
        res.json([]);
    }
});
  • Related