Reputation: 447
I'm building a filter function. I have categories and cities, that come like this: ['New York'], ['Cars']
, and I'm iterating them
to find the products of that category or city. The idea is to put on the products
variable the products that come from each city, or category, and then return them to the user.
I fail to return them because when I console log products
in the async function it's displaying the products, but although I push thos in the promises
array, that array is empty when I call Promise.all
.
I know that I need the promises to resolve so I expect to collect them in promises
and to await their resolution with Promise.all
at the end and convert the data and return all products collected, but the promises
array is empty.
import { Product } from "../../models";
import { Response } from "../../utils";
export default async function ProductsFilters(req, res) {
try {
const { Cities, Categories } = req.body;
let products = [];
let promises = [];
if (Cities.length > 0) {
Cities.map(async (city) => {
const results = await Product.find({ City: city });
return promises.push(results);
});
}
if (Categories.length > 0) {
Categories.map(async (category) => {
const results = await Product.find({ Category: category });
return promises.push(results);
});
}
const results = await Promise.all(promises);
results.map((result) => products.push(result));
if (products.length > 0) Response( res, 200, true, "Të gjitha produktet u morën me sukses.", products);
else Response(res, 404, false, "Asnjë produkt nuk u gjet në platformë.", null);
} catch (error) {
Response( res, 500, false, "Gabim i brendshëm i serverit gjatë gjetjes së produkteve.", null);
}
}
I'm using Mongo Database and Mongoose to fetch the products, so .find
function is returning the products that it matches.
Upvotes: 0
Views: 56
Reputation: 349956
The the map
method is synchronous even when you pass it a callback that is asynchronous:
Cities.map(async (city) => {
const results = await Product.find({ City: city });
return promises.push(results);
});
Those callbacks will return as soon as they encounter await
, so the promises
array will still be empty when the .map()
call returns.
Also map
returns an array, which you ignore. Instead you call push
inside the map
callback. That is bad practice. If you don't expect a returned array, then don't use map
, but forEach
or for
. If you do want to populate an array, then take benefit from the array returned by map
.
Here is a rewrite:
async function ProductsFilters(req, res) {
try {
const { Cities, Categories } = req.body;
const products = await Promise.all([
...Cities.map(async (City) => Product.find({ City })),
...Categories.map(async (Category) => Product.find({ Category }))
]);
if (products.length > 0) {
Response(res, 200, true, "Të gjitha produktet u morën me sukses.", products);
} else {
Response(res, 404, false, "Asnjë produkt nuk u gjet në platformë.", null);
}
} catch (error) {
Response(res, 500, false, "Gabim i brendshëm i serverit gjatë gjetjes së produkteve.", null);
}
}
Upvotes: 1