skip to Main Content

Attached is a node.js route for displaying product data for the product ids that a user enters in an html form. In this route, I have the array ‘prod_id_arr’ with product ids. For each prod_id in this array, I select the mysql product database row and add it to another array ‘data’. I then use the ‘data’ array to display the product data in "prod_multi_upd_pg" view at the end. When I console.log the data array, I see it is populated. However, it fails in the "prod_multi_upd_pg" view with the message "Cannot read properties of null (reading ‘prod_id’)". Interesting thing is that when I assign a single occurrence of the data array (i.e. data[0] or data[1]) to another array adata and pass the adata array to the ejs view, it works for that single item. I don’t understand how js logic works, it is very confusing. What do I have to do to display all items? Any help will be appreciated.

// Route to display current data for multiple product updates. 
app.get('/prod_multi_upd_pg', async (req, res) => {
    let prod_id_arr = req.query.prod_id_arr.split(','); 
    let data = []; 
    const fetchData = async (prod_id, index) => {
        return new Promise((resolve, reject) => {
            con.query('SELECT * FROM product WHERE prod_id = ?', [prod_id], function(err, row) {
                if (err) {
                    reject(err);
                } else {
                    resolve(row.length === 0 ? null : row);
                }   
            });
        }); 
    };  
    try {
        const dataPromises = prod_id_arr.map((prod_id, index) => fetchData(prod_id)); 
        const data = await Promise.all(dataPromises);
        res.render("prod_multi_upd_pg", {data}); --> /*this doesn't work. 
                 But when I replace this line with the following 3 
                 lines, it works for that single item.
                                    let adata = [];
                                    adata = data[0];
                                    res.render("prod_multi_upd_pg", { adata }); */
            
    } catch (error) {
        alert("Ürün kodu bulunamadı, lütfen geçerli bir ürün kodu girin.");
        res.status(500).send("Internal Server Error");
    }
})
<tbody>
              <% if(data.length){for(let i = 0; i< data.length; i++) {%>
                  <tr>
                    <td><%=data[i].prod_id%></td>
                    <td><%=data[i].saleprice%></td>
                    <td><%=data[i].stock_quantity%></td>
                    <td><%=data[i].max_order_qty%></td>
                    <td><%=data[i].time_to_cargo%></td>
                  </tr> 
              <%} }else{ %> 

2

Answers


  1. Based on your answer in comment, I maybe understand your problem.

    If you use another array (adata) and pass it to render function like this:

    res.render("prod_multi_upd_pg", { adata });
    

    It mean you are passing the data for ejs format like this:

    {
     adata: [...],
    }
    

    And in your ejs template, you checked if(data.length) pass, the data will be render. So the condition is False (Don’t have any key ‘data’ in your argument), the result is a blank html without error.

    And with res.render("prod_multi_upd_pg", {data});
    In your data has some value are null because of resolve(row.length === 0 ? null : row);

    So you can add a condition, like this:

     <% if(data.length){for(let i = 0; i< data.length; i++) {%>if(data[i]){
                      <tr>
                        <td><%=data[i].prod_id%></td>
                        <td><%=data[i].saleprice%></td>
                        <td><%=data[i].stock_quantity%></td>
                        <td><%=data[i].max_order_qty%></td>
                        <td><%=data[i].time_to_cargo%></td>
                      </tr>}
                  <%} 
    

    Hope it’s helpfull.

    Login or Signup to reply.
  2. Problems in Your Code:

    1. Incorrect Data Structure Handling.
    2. Misinterpretation of Promise Resolution.

    How to Fix the Problems:

    1. Flatten the Nested Arrays.
    2. Filter Out Null Values.

    The Fixed Code:

    app.get('/prod_multi_upd_pg', async (req, res) => {
        let prod_id_arr = req.query.prod_id_arr.split(',');
        console.log("Product IDs:", prod_id_arr); // Debugging output
    
        try {
            const dataPromises = prod_id_arr.map((prod_id, index) => fetchData(prod_id));
            let results = await Promise.all(dataPromises);
            console.log("Raw Results:", results); // Debugging output
    
            let data = results.flat().filter(item => item !== null && item.length > 0).map(item => item[0]);
            console.log("Processed Data:", data); // Debugging output
            console.log("Data Length:", data.length); // Debugging output
    
            res.render("prod_multi_upd_pg", {data});
        } catch (error) {
            console.error("Error fetching product data:", error);
            res.status(500).send("Internal Server Error");
        }
    });
    
    
    const fetchData = async (prod_id, index) => {
        return new Promise((resolve, reject) => {
            con.query('SELECT * FROM product WHERE prod_id = ?', [prod_id], function(err, row) {
                if (err) {
                    reject(err);
                } else {
                    resolve(row.length === 0 ? null : row);
                }   
            });
        }); 
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search