简体   繁体   中英

Cant remap results from mongoose find operation

I have an API route that must give me back all the invoices and so I have Invoice model. There is a supplierId field in that model, that saves the _id of the respective supplier of the invoice, which means that whenever I want to pull the invoices, I must also pull the respective suppliers and incldue them in the response, and that is my issue, for some reason, I can't work on the results as I do on normal arrays:

const getAllInvoices = async (req, res) => {
  try {
    const invoices = await Invoice.find().exec();    
    const suppliers = await suppliersService.getAllSuppliers();

    const invoicesWithSuppliers = invoices.map((invoice) => {
      return {
        number: invoice.number,
        supplierName: suppliers.find((supplier) => supplier._id === invoice.supplierId).name,
      };
    });

    console.log(invoicesWithSuppliers); // outputs nothing

    res.json(invoices); // and this now for some reason also stops working and returns {}
  } catch (err) {
    res.json(err);
  }
};

And suppliersService.getAllSuppliers() :

 const getAllSuppliers = async () => {
  try {
    const suppliers = await Supplier.find().exec();

    return suppliers;
  } catch (err) {
    return err;
  }
};

the result of find is array of Model, not a common array of object...

you can convert the result of find and working with them:

note : when you use awai, no need to exec()

let invoices = await Invoice.find(); 
invoices = invoices.map((inv) => inv.toObject({ getters: true }));
let suppliers = await suppliersService.getAllSuppliers();
suppliers = suppliers.map((sup) => sup.toObject({ getters: true }));
//do somthing

There's certainly no need to run a second query to get the suppliers data when you can just use populate() method which lets you reference documents in other collections by automatically replacing the specified paths in the document with document(s) from other collection(s).

Also, chain the lean() method to return only plain objects from the query, not mongoose documents like the find() method. It also has the benefit of less average execution time simply because the documents returned with the lean() method are plain javascript:

const getAllInvoices = async (req, res) => {
  try {
    const invoices = await Invoice.find()
        .populate('supplierId', 'name')
        .lean();    
    res.json(invoices);
  } catch (err) {
    res.json(err);
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM