-1

I am new to Javascript. I am trying to read a few files and construct a JSON object response. I am able to run the entire code, however, one last piece is remaining, I am not getting a response from the async function.

const path = require('path')
const fs = require('fs/promises');

const getProductDetailByProductID = async (id) => {
    const productsFile = path.join(__dirname, 'turing_tasks', 'products.json')
    const customersFile = path.join(__dirname, 'turing_tasks', 'customers.json')
    const reviewsFile = path.join(__dirname, 'turing_tasks', 'reviews.json')
    const imagesFile = path.join(__dirname, 'turing_tasks', 'images.json')

    const { products } = JSON.parse(await fs.readFile(productsFile, 'utf-8'))
    const product = products.filter(product => product.id === id)[0]

    const {reviews} = JSON.parse(await fs.readFile(reviewsFile, 'utf-8'))
    const {customers} = JSON.parse(await fs.readFile(customersFile, 'utf-8'))
    const {images} = JSON.parse(await fs.readFile(imagesFile, 'utf-8'))

    const reviewsData = []
    reviews.forEach((review) => {
        customer = customers.filter(customer => customer.id === review.customer_id)
        if(customer) customer = customer[0]
        const reviewImages = images.filter(image => review.images.includes(image.id))

        reviewsData.push({
            "id": review.id, 
            "rating": review.rating,
            "customer": customer,
            "images": reviewImages
        })
    })

    return {
                    "id": product.id,
                    "name": product.name,
                    "reviews": reviewsData
                }
}
(async () => {
  const result = await getProductDetailByProductID(1);
  return result
})();  // This does not fetch anything

I am running this file using below command

nodemon task.js
                    

Also, please recommend a better way of writing this code if it is poorly written. Please share a link for the same.

wayne
  • 393
  • 2
  • 13
  • 2
    An async function returns a Promise. You need to use `Promise.resolve` or `getProductDetailByProductID(1).then(...)` to get the result. – Tim Roberts Jul 18 '23 at 07:08
  • 1
    Did you use the await keyword? Async function returns a promise, you get the result of the promise with the await keyword – Mehriddin Nozimov Jul 18 '23 at 07:09
  • 1
    Mixing `await` with `.then()` is a great way to produce very confusing code. I suggest you stick to one form and one form only – Phil Jul 18 '23 at 07:19
  • @Phil what is the right way of simplifying the code. Please suggest some link. – wayne Jul 18 '23 at 07:23
  • 1
    Just don't use `.then()`. Write the code as if it was all synchronous but use `await` for any async operations. For example... `const { products } = JSON.parse(await fs.readFile(...)); const product = products.find((p) => p.id === id);` – Phil Jul 18 '23 at 07:25
  • @Phil Awesome thanks. Can you please recommend me how to become good at writing promises? Any good practice material online that takes you from beginner to advanced level? – wayne Jul 18 '23 at 07:41
  • 2
    https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous – Phil Jul 18 '23 at 07:44

1 Answers1

0

because your getProductDetailByProductID is async, you should call your getProductDetailByProductID like this:

(async () => {
  const result = await getProductDetailByProductID(1);
  console.log(result);
})();

more:

getProductDetailByProductID // this function is async and return a Promise value

if you want get the value:

function ss ()  {
  const result = await getProductDetailByProductID(1);
  console.log(result); // your getProductDetailByProductID's return value
  return result;
}
ss()

if you still return value from async function, also need use async await to get value

sync function s2() {
  const result = await ss();
  console.log(result);
}
MWY
  • 1,071
  • 7
  • 15
  • I have updated my code, however this time IIFE from your answer does not return a response. It only logs the response. I have tried return result. Can you please help? – wayne Jul 18 '23 at 07:56
  • @wayne, don't worry, I will explain to you. – MWY Jul 18 '23 at 08:13
  • The result would also be asynchronous so you also need to await it: `let x = await (async () => { .....; return result})()` – slebetman Jul 18 '23 at 08:17
  • @wayne, I understand what you mean. But since it's an async function, if you want to get the return value inside the async function, you have to use `Promise().then()` or `await` to get the value. `async function ss () { const result = await getProductDetailByProductID(1); console.log(result); return result; } (async function s2() { const result = await ss(); console.log(result); })()` – MWY Jul 18 '23 at 08:24
  • @MWY This is working, however it is confusing as it is a chain of function calls. Can you please update your answer as well – wayne Jul 18 '23 at 08:36
  • 1
    @wayne, sure, explain more – MWY Jul 18 '23 at 08:41