Хорошо,
Я довольно новичок в node.js и в целом концепции функций обратного вызова, и я ломал голову, пытаясь понять это. Может быть, некоторые из вас, ребята, могут помочь.
Итак, основная настройка заключается в том, что у меня есть приложение React / Redux на внешнем интерфейсе, которое использует API в качестве источника данных. Спереди я хочу загрузить некоторое количество продуктов одновременно и загрузить все их изображения, затем у меня есть компонент Product, который показывает один продукт и отображает галерею изображений (поэтому мне нужны все изображения продуктов на один раз)
Я пытаюсь написать API, когда запрашиваю http://myapi.com/randomproducts/, который будет возвращать указанное количество случайных продуктов из базы данных MySQL. Эта часть у меня есть. Вот часть, которая бросает меня ... каждый продукт, который я возвращаю в этом массиве продуктов, имеет неизвестные изображения, связанные с ним. Я хочу загрузить их в одно и то же время, чтобы мои возвращаемые данные выглядели примерно так:
[
{
product_id: 0,
product_name: "my cool product",
product_desc: "desc of my cool product",
price: 10.00,
product_images: [
{
product_image_id: 10,
product_image: "img1.jpg",
},
{
product_image_id: 11,
product_image: "img2.jpg",
},
{
product_image_id: 12,
product_image: "img3.jpg",
}
]
},
{
product_id: 2,
product_name: "my other cool product",
product_desc: "desc of my other cool product",
price: 20.00,
product_images: [
{
product_image_id: 13,
product_image: "img21.jpg",
},
{
product_image_id: 14,
product_image: "img22.jpg",
},
{
product_image_id: 15,
product_image: "img23.jpg",
}
]
},
]
... и т. Д.
Таким образом, очевидно, что есть отношения родитель-потомок между products (родительская таблица) и product_images (дочерняя таблица). К сожалению, мне не удалось создать API-функцию, которая будет возвращать массив изображений, который также имеет массив связанных изображений. Конечная цель состоит в том, чтобы я хотел загружать сразу несколько продуктов и связанных с ними изображений за один вызов API, вместо того чтобы получать продукты, а затем получать изображения.
Вот снимок таблиц базы данных:
НАЖМИТЕ ЗДЕСЬ, ЧТОБЫ ПОСМОТРЕТЬ ТАБЛИЦЫ БАЗЫ ДАННЫХ
Вот код, который у меня есть:
1. МАРШРУТ
Отправьте текст / json body на этот маршрут. Он принимает идентификатор пользователя и количество возвращаемых продуктов:
app.route('/multiplerandomproducts/')
.post(products.get_multiple_random_products);
post body: {user_id: <num>, product_count: <num>}
2. ПОЛУЧЕНИЕ МОИХ ПРОДУКТОВ
В моем контроллере ProductsController.js у меня есть следующее:
exports.get_multiple_random_products = function(req,res) {
var postData = new Product(req.body);
Product.getMultipleRandomProducts(postData.data, function(err,products) {
if(err) {
res.send(err);
} else {
res.json(products);
}
});
}
В моей модели Products.js у меня есть следующее:
// get a random product for the userId
Product.getMultipleRandomProducts = function getMultipleRandomProducts(postData, result) {
var userId = postData.user_id;
var productCount = postData.product_count;
var sqlStr = "SELECT DISTINCT a.* FROM product a "
+ " INNER JOIN product_category b ON b.product_id = a.product_id "
+ " INNER JOIN user_category c ON c.category_id = b.category_id "
+ " WHERE c.user_id= ? "
// get only products that the user hasn"t seen before
if(process.env.APP_HIDESEENPRODS === "1") {
sqlStr += " AND a.product_id NOT IN (SELECT c.product_id from seen_product c WHERE c.user_id = ?)";
}
sqlStr += " ORDER BY RAND() LIMIT ?";
sql.query(sqlStr, [userId, userId, productCount], function(err, res) {
if(err) {
result(err, null);
} else {
// hide from the use if this flag is set in the app
if(!process.env.APP_HIDESEENPRODS === "1") {
insertUserSeenProduct(userId, res[0].product_id);
}
result(null,res);
}
});
}
У меня также есть модель ProductImages.js, которая в качестве метода получения изображений для определенного продукта выглядит следующим образом:
ProductImage.getAllProductImages = function getAllProductImages(productId, result) {
sql.query("Select * from product_image WHERE product_id = ? ", productId, function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else {
result(null, res);
}
});
};
Что я пробовал:
Так что это версия моей функции, которую я пытался реализовать. Когда я указываю, что хочу три записи, я получаю объект с тремя нулевыми значениями, то есть [ноль, ноль, ноль]. Я думаю, что я близко, просто не вижу, что я делаю неправильно ....
Product.getMultipleRandomProducts = function getMultipleRandomProducts(postData, result) {
var userId = postData.user_id;
var productCount = postData.product_count;
var sqlStr = "SELECT DISTINCT a.* FROM product a "
+ " INNER JOIN product_category b ON b.product_id = a.product_id "
+ " INNER JOIN user_category c ON c.category_id = b.category_id "
+ " WHERE c.user_id= ? "
// get only products that the user hasn"t seen before
if(process.env.APP_HIDESEENPRODS === "1") {
sqlStr += " AND a.product_id NOT IN (SELECT c.product_id from seen_product c WHERE c.user_id = ?)";
}
sqlStr += " ORDER BY RAND() LIMIT ?";
sql.query(sqlStr, [userId, userId, productCount], function(err, res) {
if(err) {
result(err, null);
} else {
// hide from the use if this flag is set in the app
if(!process.env.APP_HIDESEENPRODS === "1") {
insertUserSeenProduct(userId, res[0].product_id);
}
result(null, res.map((item) => {
sql.query("Select * from product_image WHERE product_id = ? ", item.product_id, function (err, res2) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else {
item.product_images = res2;
}
});
}));
}
});
}
Проблема, с которой я сталкиваюсь:
Итак, я попытался просто перебрать возвращенный массив продуктов, в который я вернулся, и получить изображения продуктов, которые работали бы хорошо, если бы это не было асинхронным. Но когда я пытаюсь это сделать, я возвращаю объект с тремя продуктами (если я запрашиваю три), но только одному (первому) из этих продуктов назначены изображения.
Итак, я хочу вернуть один объект, который выглядит примерно так:
- Продукт
- изображение
- изображение
- изображение
- Продукт
- изображение
- изображение
Продукт
- изображение
- изображение
- изображение
Итак, может кто-нибудь, пожалуйста, Скажите, пожалуйста, как я могу это сделать? Я все еще пытаюсь обернуться вокруг функций обратного вызова, и у меня скоро будет аневризма мозга!
Спасибо !!