skip to Main Content

I am currently not very good at express. I am struggling to make a post request work. I would like the post request to add an item to a cart.json file, using Node js’s fs.fileRead and fs.fileWrite. For some reason, the changes are not coming up in console.log, and is giving me this error in the browser:

browser localhost error screenshot

The endpoint for the form for the post request looks very different:

app.get('/merch/:product_name', (req, res) => {
...
} 

Here is the code for the post request:

app.post('/cart', (req, res) => {
    const { branch, product_name, category, style, flavor, quantity } = req.body;

    const newCartItem = {
        id: uuid(),
        branch, 
        product_name,
        category,
        style,
        quantity
    }

    const readFile = async () => {
        const fileContent = await new Promise((resolve, reject) => {
            return fs.readFile(__dirname + "/data/cart.json", 'utf-8', (err, data) => {
                if (err) {
                    title = "Error"
                    res.render('/error', { title, err })
                } else if (data) {
                    const fileData = JSON.parse(data)

                    if (branch === 'frozen-treats') {
                        fileData['frozen_treats'] = [...fileData.frozen_treats, newCartItem];
                    } else if (branch === 'merch') {
                        fileData['merch'] = [...fileData.merch, newCartItem];
                    }

                    fs.writeFile(__dirname + "/data/cart.json", JSON.stringify(fileData, null, 2), 'utf-8', (err, data) => {
                        if (err) {
                            title = "Error";
                            console.log(err);
                            res.render('/error', { title, err });
                        } else if (data) {
                            resolve(data)
                            res.end(JSON.stringify(data, null, 2));
                        }
                    })

                }
            })
        })

        return fileContent;

        
    }

})

If you have any suggestions as to what might be going on, please let me know.

Thank you

2

Answers


  1. Chosen as BEST ANSWER

    The fileData[branch].push(newCartItem); part from Jigar's answer helped in forming a solution

    Here is the solution:

    app.post('/cart', (req, res) => {
        const { branch, product_name, category, style, flavor, quantity } = req.body;
    
        let newCartItem;
    
        if (branch === "merch") {
            newCartItem = {
                id: uuid(),
                branch,
                product_name,
                category,
                style,
                quantity
            }
        } else if (branch === "frozen-treats") {
            newCartItem = {
                id: uuid(),
                branch,
                product_name,
                flavor,
                quantity
            }
        }
    
        const readFile = () => {
            return new Promise(async (resolve, reject) => {
              fs.readFile(__dirname + "/data/cart.json", "utf-8", async (err, data) => {
                if (err) {
                  const title = "Error";
                  res.render("/error", { title, err });
                  reject(err);
                }
                const fileData = await JSON.parse(data);
    
                fileData[branch].push(newCartItem);
    
                fs.writeFile(__dirname + "/data/cart.json", JSON.stringify(fileData, null, 2),"utf-8",(err, writeData) => {
                    if (err) {
                      const title = "Error";
                      res.render("/error", { title, err });
                      reject(err);
                    }
                    resolve(writeData);
                  }
                );
              });
            });
        };
    
        readFile()
            .then(() => {
                res.redirect(`/${branch}/${product_name}?category=${category !== undefined ? category : flavor}`);
            })
            .catch((err) => {
                res.redirect('/error')
            });
    })
    

    There were a couple of things that I needed to revise to get the post request working properly.

    When some variables from req.body would be destructured, their value would come back as undefined. This is going to be a problem if I want to work with json, because according to this other post, "'Undefined' is not a valid json value..." (2019).

    In that case, before doing JSON.stringify on the newly made cart item entry, I needed to exclude the values that wouldn't make sense depending on where the post request came from i.e. a merch item wouldn't have a flavor, a frozen-treats item wouldn't have a style.

    Another thing I noticed was how the new data was being written to the cart.json file. It seems that fs.fileWrite rewrites the whole file with the new entry, discarding all previous data. This means that it gets rid of the two branches (frozen-treats and merch) that I specifically wrote for the cart.json file.

    To fix this, I had to make a copy of all of the previous data:

    const fileData = await JSON.parse(data);

    Next, push the new cart item to the specific branch the post request came from:

    fileData[branch].push(newCartItem)

    And finally, do fs.fileWrite with the newly updated data that also contains the previous data as well. That way, no data is lost.

    So far, no errors appear anywhere. Thank you all for your help!


  2. you’ve made some minor mistakes here:

    First, you should not use promise like this:

    const fileContent = await new Promise((resolve, reject) => {});
    

    But instead you can write like:

    const fileContent = new Promise(await(resolve, reject) => {});
    

    I’ll provide you with some changes have a look maybe it will be helpful for you:

        app.post("/cart", (req, res) => {
      const { branch, product_name, category, style, flavor, quantity } = req.body;
    
      const newCartItem = {
        id: uuid(),
        branch,
        product_name,
        category,
        style,
        quantity
      };
    
      const readFile = () => {
        return new Promise(async (resolve, reject) => {
          await fs.readFile(__dirname + "/data/cart.json", "utf-8", async (err, data) => {
            if (err) {
              const title = "Error";
              res.render("/error", { title, err });
              reject(err);
            }
            const fileData = JSON.parse(data);
            fileData[branch] = [];
            fileData[branch].push(newCartItem);
            await fs.writeFile(__dirname + "/data/cart.json", JSON.stringify(fileData, null, 2),"utf-8",(err, writeData) => {
                if (err) {
                  const title = "Error";
                  res.render("/error", { title, err });
                  reject(err);
                }
                resolve(writeData);
                res.end(JSON.stringify(writeData, null, 2));
              }
            );
          });
        });
      };
    
      readFile()
        .then(() => {})
        .catch((err) => {});
    });
    

    I hope it’ll helpful for you 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search