繁体   English   中英

使用node.js API从子表加载记录

[英]Loading Records from a child table with a node.js API

好,

我对node.js和回调函数的整个概念还很陌生,我一直在绞尽脑汁试图弄清楚这一点。 也许你们中的一些人/女孩可以提供帮助。

因此,基本设置是我在前端有一个使用API​​作为数据源的React / Redux应用程序。 在前面,我想一次加载一些产品并加载其所有图像,然后我有一个Product组件,它显示一个产品,并显示一个图片库(这就是为什么我需要所有产品图像的原因一旦)

当我请求http://myapi.com/randomproducts/时,我试图编写一个API,它将从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",
          }
    ]
  },

]

... 等等。

因此很显然, 产品 (父表)和product_images (子表)之间存在父子关系。 不幸的是,我没有成功创建一个API函数,该函数将返回图像数组,该图像数组也具有相关图像数组。 最终目标是我想在一个API调用中一次加载多个产品及其关联的图像,而不是先获得产品,再获得图像。

这是数据库表的快照:

单击此处查看数据库表

这是我的代码:

1.路线

将text / json正文发送到此路由。 它接受一个userId和许多要返回的产品:

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);
                }
            });   
    };

我尝试过的:

这是我尝试实现的函数版本。 当我指示我想要三个记录时,我得到一个具有三个空值的对象,即[null,null,null]。 我想我很亲密,只是看不到我在做错什么...。

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;
                    }
                });                  
            }));
        }

    });
}

我遇到的问题是:

因此,我尝试简单地遍历返回的产品数组并返回产品图像,如果这不是异步的,则可以很好地工作。 但是,当我尝试此操作时,我返回了一个带有三个产品的对象(如果我要三个),但是只有一个(第一个)产品为其分配了图像。

总而言之,我想返回一个看起来像这样的对象:

  • 产品
    • 图片
    • 图片
    • 图片
  • 产品
    • 图片
    • 图片
    • 图片
  • 产品
    • 图片
    • 图片
    • 图片

那么,有人可以请告诉我我该怎么做? 我仍然在努力围绕回调函数,而我将要患有脑动脉瘤!

谢谢!!

因为每种产品的图像都是单独获取的,所以预期的结果就是您现在所获得的。 实际上,如果您使用服务器(不是本地服务器),则没有图像返回到任何产品的机会。

使用async/awaitpromisify您的函数获取生产映像:

sql.query(sqlStr, [userId, userId, productCount], async 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);
        }

        // Get the list of images thru promisify
        const getImages = function(item) {
            return new Promise( function(resolve, reject) {
                sql.query("Select * from product_image WHERE product_id = ? ", item.product_id, function (err, res2) {
                    if(err) {
                        console.log("error: ", err);
                        reject(result(null, err));
                    }
                    else {
                        item.product_images = res2;

                        resolve(item);
                    }
                });
            });
        };

        let products = [];

        const returnFalse = () => false;

        for (let i = 0; i < res.length; i++ ) {
            let product = await getImages(res[i]).catch(returnFalse);

            if (product) {
                products.push(product);
            }
        }

        result( null, products);
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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