-3
/**
 * This function calculates the cost of an employee based on the data in its file
 * @param {string} filePath - path to the employee data file
 * @returns {{name: string, cost: number}} - the name and cost of the employee
 */

function costCalculator(filePath) {
    const fs = require("fs");
    fs.readFile(`${filePath}`,"utf8",(err,data)=>{
        if(err){
            console.error(err);
            return;
        }
        var employee=JSON.parse(data);
        let cph=employee["salary"]/employee["hours"];
        var result={name:employee["name"],cost:cph};    
        console.log(result);
    });

    
}
console.log(costCalculator('mohamed.json'));

it returns

undefined
{ name: 'Mohamed', cost: 62.5 }

when I expect only

{ name: 'Mohamed', cost: 62.5 }
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
  • 1
    Your function returns undefined, because you don't have any return statement. And that's what's logged in the console. Inside of your function, you have another console.log. that's the second output – derpirscher Aug 30 '23 at 17:36
  • @derpirscher The log messages seem to be in the wrong order. It should log the object inside the function, then log `undefined` when it returns. – Barmar Aug 30 '23 at 17:37
  • Since the function doesn't return anything, there's no point in logging the result. Just call the function without `console.log()`. – Barmar Aug 30 '23 at 17:38
  • @Barmar why, the inner console.log happens in the callback of `readFile`. This will obviously be executed after any synchronous code – derpirscher Aug 30 '23 at 17:40
  • @derpirscher Oops, forgot that it was async. – Barmar Aug 30 '23 at 17:43
  • Even when taking a step back from asynchronous operations in general, consider basic logic... *"when I expect only..."* - Why? Your code contains two `console.log` statements, so why would the expectation not include two `console.log` outputs? (Regardless of what those outputs are.) – David Aug 30 '23 at 17:44

1 Answers1

0

why does my fs.readFile function return undefined and the expected answer?

It doesn't. return is not present anywhere in your code, console output and return values are very different things.

The reason your program outputs two lines is that you are outputting {name: ...} line from your console.log(result); at the end of costCalculator, and then wrapping your function invocation in a redundant and unnecessary console.log.

console.log(costCalculator('mohamed.json')) doesn't make sense. That function doesn't return anything, so its return value is implicitly undefined. You are logging that undefined value, in addition to the callback inside the function's own log output.

Your function is document with:

@returns {{name: string, cost: number}}

It certainly does not. It returns nothing; console.log is not how you return a value. If you need to return something from an asynchronous call, there is a well-answered question on that topic here: How do I return the response from an asynchronous call?

user229044
  • 232,980
  • 40
  • 330
  • 338