'node.js moongose find populate cant access to array

I have this in my backend:

ad = await Ad.find({'company': companyId}).populate('creator');

And when i console.log(ad) i get this:

[
  {
    connections: [],
    status: 1,
    _id: 6047c711b1f8cf1c98b2227c,
    title: "DOTA: Dragon's Blood | Teaser | Netflix",
    company: 6047c6fab1f8cf1c98b2227a,
    video: 'uploads\\videos\\7802d640-810a-11eb-83c2-57e23ae6d491.mp4',
    creator: {
      companies: [Array],
      ads: [Array],
      _id: 6047c6e7b1f8cf1c98b22279,
      name: 'test test',
      email: '[email protected]',
      image: 'uploads\\images\\5f3ea850-810a-11eb-83c2-57e23ae6d491.jpeg',
      password: '',
      __v: 3
    },
    __v: 0
  },
  {
    connections: [ 6047c745b1f8cf1c98b22280, 6047c83bb1f8cf1c98b22286 ],
    status: 1,
    _id: 6047c72cb1f8cf1c98b2227f,
    title: 'Diretide 2020',
    company: 6047c6fab1f8cf1c98b2227a,
    video: 'uploads\\videos\\87a97d60-810a-11eb-83c2-57e23ae6d491.mp4',
    creator: {
      companies: [Array],
      ads: [Array],
      _id: 6047c6e7b1f8cf1c98b22279,
      name: 'test test',
      email: '[email protected]',
      image: 'uploads\\images\\5f3ea850-810a-11eb-83c2-57e23ae6d491.jpeg',
      password: '',
      __v: 3
    },
    __v: 6
  }
]

But when i try to console.log(ad.creator) or console.log(ad.creator.ads) im getting undefined error.. I need this becasue i want to pull some things from ad.creator.ads.. Do i miss something in my code?


I will try to be more specific i tried but i cant figure how to do this:

ad.js:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const adSchema = new Schema({
  title: { type: String, required: true },
  description: { type: String, required: true },
  video: { type: String, required: true },
  company: { type: mongoose.Types.ObjectId, required: true, ref: 'Company' },
  creator: { type: mongoose.Types.ObjectId, required: true, ref: 'User' },
  connections: [{type: mongoose.Schema.ObjectId, ref: 'User'}],
  status: {type: Number, default: '1'}
});

module.exports = mongoose.model('Ad', adSchema);

So i need here when i delete this company to also pull all companies from user.. This is user.js

const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');

const Schema = mongoose.Schema;

const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true, minlength: 6 },
  image: { type: String, required: true },
  companies: [{ type: mongoose.Types.ObjectId, required: true, ref: 'Company' }],
  ads: [{ type: mongoose.Types.ObjectId, required: true, ref: 'Ad' }]
});

userSchema.plugin(uniqueValidator);

module.exports = mongoose.model('User', userSchema);

process for deleting company in // i specified part with problem where need to pull ads from user for this:

const deleteCompany = async (req, res, next) => {
  const companyId = req.params.cid;

  let company;
  let ad;
  try {
    company = await Company.findById(companyId).populate('creator');
    ad = await Ad.find({'company': companyId}).populate('creator');
  } catch (err) {
    const error = new HttpError(
      'backend_message13',
      500
    );
    return next(error);
  }

  if (!company) {
    const error = new HttpError('backend_message14', 404);
    return next(error);
  }

  if (company.creator.id !== req.userData.userId) {
    const error = new HttpError(
      'backend_message15',
      401
    );
    return next(error);
  }

  const imagePath = company.image;

  try {
    const sess = await mongoose.startSession();
    sess.startTransaction();
    await company.remove({ session: sess });

    company.creator.companies.pull(company);
    await company.creator.save({ session: sess });
    
    // here is the path where is problem i also tried with ad[0]
    ad.creator.pull(ad.creator.ads);
    await ad.creator.save({ session: sess });
    //

    await Ad.deleteMany({'company': companyId});

    await sess.commitTransaction();
  } catch (err) {
    const error = new HttpError(
      err,
      500
    );
    return next(error);
  }

  fs.unlink(imagePath, err => {
    console.log(err);
  });

  ad.forEach(function (item) {
    const videoPath = item.video;
    const thumb = item.video.replace("uploads\\videos\\","uploads\\videos\\thumb\\").replace(".mp4", "_screenshot.jpeg");

    fs.unlink(videoPath, err => {
      console.log(err);
    });
    fs.unlink(thumb, err => {
      console.log(err);
    });
  });

  res.status(200).json({ message: 'backend_message17' });
};

Thanks for help :)



Solution 1:[1]

append lean() mean on populate and then see
ad = await Ad.find({'company': companyId}).populate('creator').lean();

Solution 2:[2]

The query Ad.find() returns an array - but your code tried to access it as an object:

ad = await Ad.find({'company': companyId}).populate('creator');
console.log(ad.creator)

ad.creator actually is an undefined

Use an index to access required array element:

ad = await Ad.find({'company': companyId}).populate('creator');
console.log(ad[0].creator)

Or switch to Ad.findOne()

Sources

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

Source: Stack Overflow

Solution Source
Solution 1 Anurag Arwalkar
Solution 2