Почему выводятся все посты вместо одной конкретной
В чем проблема? Хочу чтобы при клике на ссылку шел запрос на 3 модели и искал у каждой тот запрос, который я указал. И в зависимости что вернется, должно отображаться на динамической странице. Но при переходе на эту самую страницу я получаю просто тот результат, который я указываю вторым параметром в функции findInModal. Тоесть постоянно рендерятся данные из той модели и все. Я надеялся, что мне будет приходить null при поиске в каждой модели и я фильтровал бы вывод. Но почему-то мне даны все посты сразу. В каждой модели что-то находит и возвращает. Как-то странно!
const Tag = require("../models/tag.model");
const Card = require("../models/card.model");
const Post = require("../models/post.model");
function findInModels() {
const args = [...arguments];
if (args.length < 2) {
const result = Promise.reject("Должно быть не менее 2 аргументов");
return [result];
}
const value = args.shift();
return args.map(model => {
const modelName = model.constructor.name.toLowerCase();
const queryParams = Object.defineProperty({}, modelName, { value });
return model.findOne(queryParams);
});
}
module.exports.getData = async (req, res) => {
const { slug } = req.params;
try {
const promises = findInModels(slug, Card, Tag, Post);
const response = await Promise.allSettled(promises);
const articles = response.filter(article => article !== undefined);
const article = articles.length ? articles.shift() : null;
return res.json(article);
} catch (err) {
res.status(500).json(err);
}
};
Ответы (1 шт):
В коде ты не правильно работаешь с результатом Promise.allSettled(). Вот что пишут в документации:
Возвращаемое значение
Promise, который будет выполнен после завершения каждого промиса, вне зависимости от того выполнился он успешно или был отклонён. В то же время, в возвращаемый обработчик промиса передаётся массив, который содержит результат каждого промиса в исходном наборе промисов.
Объект каждого результата содержит свойство status. Если status имеет значение fulfilled (выполнено), то объект будет содержать свойство value. Если status имеет значение rejected (отклонено), то объект будет содержать свойство reason. Свойство value (или reason) будет содержать значение с которым был выполнен (или отклонён) промис.
Кроме того, в коде ты используешь сложный function.arguments, который, кстати, deprecated. Вместо него нужно использовать новый удобный и простой spread ....
Вот что получилось:
NB: вместо моделей нарисованы объекты-заглушки
const findOne = async function () {
return new Array(5).fill(1).map((_, id) => ({ id, _classname: this.name }));
};
const Tag = { name: 'Tag' };
const Card = { name: 'Card' };
const Post = { name: 'Post' };
Tag.findOne = findOne.bind(Tag);
Card.findOne = findOne.bind(Card);
Post.findOne = findOne.bind(Post);
function findInModels(value, ...models) {
if (models.length === 0) {
throw new Error('Модели должны быть указаны');
}
return models.map((model) => {
const modelName = model.name.toLowerCase();
return model.findOne({
value, modelName
});
});
}
async function getData(req) {
const { slug } = req.params;
try {
const promises = findInModels(slug, Card, Tag, Post);
const response = await Promise.allSettled(promises);
const articles = response.reduce((acc, item) => {
if (item.status === 'fulfilled') {
acc = acc.concat(item.value || []);
}
return acc;
}, []);
const article = articles.shift();
console.log(article);
console.log(articles.length);
} catch (err) {
console.error(err);
}
}
getData({ params: { slug: 'ab' } });