0

enter image description hereI have existing products.json data which consists of an array of data, I wanted to push a new json object on a post request. While the array of json objects gets updated but when I open the product.json file I don't see the newly added data in that file. And I get an error like this

[Error: ENOENT: no such file or directory, open '../data/products.json'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '../data/products.json'
}

Folder Structure

 controllers
     productController.js
models
     productModels.js 
data
   products.js
node_modules
package.json
package-lock.json
server.js

product controller file

export const createProduct = async (req, res) => {
    try{
        const product = {
            userId: 'req.userId',
            id: 'req.id',
            title: 'req.title',
            body: 'req.body'
        }
        const newProduct = await create(product)
        res.writeHead(201, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(newProduct))
    }catch(err){
        console.log(err)
    }
}

product model file

export const create = (product) => {
    const id = uuid()
    const newProduct = {...product, id}
    products.push(newProduct)

    writeDataToFile('../data/products.json', products)

    const promise = new Promise((resolve, reject) => {
        const newProduct = products.find(element => element.id = id)
        setTimeout(() => {
            resolve(newProduct)
        }, 1000)
    })
    return promise
}

utils.js file

import { writeFile } from 'fs/promises';

export const writeDataToFile = async (filename, content) => {
    try {
        console.log(filename)
        console.log(process.cwd())
        await writeFile(filename, JSON.stringify(content));      
      } catch (err) {
        console.error(err);
      }
}

enter image description here

enter image description here

Nishant Kumar
  • 691
  • 1
  • 11
  • 31

1 Answers1

1

It seems the path is incorrect and thats why it is not updating the file.


import { writeFile } from 'fs/promises';
import * as path from 'path';

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export const writeDataToFile = async (filename, content) => {
    try {
        console.log(filename)
        console.log(process.cwd());
        console.log(path.join(__dirname, filename)) // check if the path is correct
        await writeFile(path.join(__dirname, filename), JSON.stringify(content));      
     return 'File Updated';
      } catch (err) {
        console.error(err);
      }
}

You might need to await for the file operation to perform:


export const create = (product) => {
    const id = uuid()
    const newProduct = {...product, id}
    products.push(newProduct)

    await writeDataToFile('../data/products.json', products)

    const promise = new Promise((resolve, reject) => {
        const newProduct = products.find(element => element.id = id)
        setTimeout(() => {
            resolve(newProduct)
        }, 1000)
    })
    return promise
}
Apoorva Chikara
  • 8,277
  • 3
  • 20
  • 35
  • It's not working, I get error, "ReferenceError: __dirname is not defined". I haven't made any mistake in importing the path module. – Nishant Kumar Oct 27 '21 at 12:23
  • 1
    Yes, You are using es module system and it won't work with this directly. I have added the code check with this. – Apoorva Chikara Oct 27 '21 at 13:00
  • I can successfully write the file, the product.json file gets updated but now when I create a request the server sends a response "Error: Server returned nothing (no headers, no data)" – Nishant Kumar Oct 27 '21 at 13:59
  • Great, I believe you can ask a new question for that. As this question(initially what you have asked) is resolved, the answer should be marked and upvote for future reference. – Apoorva Chikara Oct 27 '21 at 14:03
  • @Approva I upvoted your answer now please help me because, What I see is, if the file doesn't get updated then the server sends a success response and if the file gets updated then the server returns "Error: Server returned nothing (no headers, no data)". So it's still part of the same question. – Nishant Kumar Oct 27 '21 at 14:11
  • Can you add the function where you are sending the response. It seems you should send the response once the file is updated. You must be sending the response before the file gets updated. – Apoorva Chikara Oct 27 '21 at 14:13
  • I've already included that file, please take a look at the product controller file – Nishant Kumar Oct 27 '21 at 14:17
  • I have udpated the code, the only thing is you need to wait for the write file function to update the file first and then send the data. What I see in the question code is your are sending the data not the file. Put debugger or console to check the flow of the methods. I'm sure you will find it. – Apoorva Chikara Oct 27 '21 at 14:24
  • Yes, I tried this, await writeDataToFile(path.resolve(__dirname, '../data/products.json') also I made the create function async but it still doesn't show any error in the console either neither I get any response from the server. – Nishant Kumar Oct 27 '21 at 14:28
  • export const create = async (product) => { try{ const id = uuid() const newProduct = {...product, id} products.push(newProduct) await writeDataToFile(path.resolve(__dirname, '../data/products.json'), products) const promise = new Promise((resolve, reject) => { const newProduct = products.find(element => element.id = id) setTimeout(() => { resolve(newProduct) }, 1000) }) return promise }catch(err){ console.log(err) } } – Nishant Kumar Oct 27 '21 at 14:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238605/discussion-between-nishant-kumar-and-apoorva-chikara). – Nishant Kumar Oct 27 '21 at 14:30
  • 1
    You are welcome . – Apoorva Chikara Oct 27 '21 at 17:16