Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

370
Vistas
How to await inside 2 map functions and retrieve documents from mongoDB

I need to perform some modification on an API that returns something like this:

[
  {
    "_id": "0000000000000000001",
    "name": "Random name",
    "categories": [
        "5eb8548330550e017f8902e6",
        "5eb2548630550e117f8909eb",
        "5eb6548930550e017f8909e9"
    ]
  },
  {...},
]

each results' categories are returned as ids of their respective documents. I need to manipulate the result so each object's categories field has an array of objects and each object has the id and the name of its category. I make an example of what the outcome should be:

[
  {
    "_id": "0000000000000000001",
    "name": "Random name",
    "categories": [
      {"_id": "5eb8548330550e017f8902e6",
      "name": "Category 1"},
      {"_id": "5eb2548630550e117f8909eb",
      "name": "Category 2"},
      {"_id": "5eb6548930550e017f8909e9",
      "name": "Category 3"},
    ]
  },
  {...},
]

I need to do this using plain JS and for so far this is what I have done but it returns an array of undefined:

const resultArray = await Promise.all(
  searchResults.map(async (item) => {
    item.categories.map(async (categoryId) => {
      return await CategoryType.find({ _id: categoryId});
    });
  })
);

For the moment I am trying to get each category document for each id in the categories field. I bet the reason why I am getting an array of undefined is that I am handling async in the wrong way but cannot figure out how.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

To strictly answer your question: you are missing synchronization (because Array.prototype.map 'ignores' async):

const resultArray = await Promise.all(
  searchResults.map(async (item) => {
    const promises = item.categories.map(async (categoryId) => {
      // you dont want find, but findOne btw
      return await CategoryType.findOne({ _id: categoryId});
    });
    const categories = await Promise.all(promises)
    item.categories = categories
    return item
  })
);

This can be simplified down as

const resultArray = await Promise.all(
  searchResults.map(async item => {
    item.categories = await Promise.all(item.categories.map(categoryId => {
      return CategoryType.findOne({ _id: categoryId})
    }))
    return item
  })
);

But the proper way of doing it is likely to use populate

const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/dummy')

const Category = mongoose.model('Category', {
  name:String,
}, 'categories');
const X = mongoose.model('X', {
  name:String,
  categories: [{type: mongoose.Types.ObjectId, ref: 'Category'}]
}, 'xs');

;(async()=>{
  try {
  mongoose.set('debug', true)

  const xs = await X.find().populate('categories')

  console.log('xs : ', xs[0])
  } finally {
    mongoose.disconnect()
  }
})()

You will notice by the way, that mongoose, under the hood uses find({ _id: {$in:[]}}) which makes only one request (so better) than doing multiple findOne (as you do)

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda