0

I was trying to build a generic function which will append to a file. Depending on the outcome the function will either return status of 200 or 500.

The initial set up should call the function and return either of statuses. After invoking the method, I am receiving an empty object.

The function is part of a class, and all required imports have added. I did try to return an fs.appendFile but I manage to receive the same result.

/**
 * A functio which writes a data into a file
 * @param  {[string]} fileName A file location with file name string
 * @param  {[string]} msg      A data to be saved
 * @return {[object]}          A response object with response code and msg.
 */
static toFile(fileName, msg) {
    fs.appendFile(fileName, msg, function(err) {
        let responseObject = {};
        if (err) {
            responseObject.status = 500;
            responseObject.msg = 'Error occured please view ' + fileName;
            return responseObject;
        }
        responseObject.status = 200;
        responseObject.msg = 'Success, file has been created ' + fileName;

        return responseObject;
    });
}
NashPL
  • 461
  • 1
  • 4
  • 19
  • 4
    `toFile` doesn't return anything; I'm not sure what you expect. I think you're just confused about how async programming works in general. Pass a function to `toFile` that you call with the `responseObject` from `fs.appendFile`, or promisfy it, or any number of other ways to deal with async code. – Dave Newton Apr 26 '18 at 14:28
  • 1
    Your documentation is a lie. `toFile` isn't returning anything. `fs.appendFile` returns something, but `toFile` doesn't propagate. Write `return fs.appendFile(){...}` – zero298 Apr 26 '18 at 14:29
  • 1
    Yes, I am aware that my doc is a wrong because I would like to make sure it returns something back once it's done. Thanks @JaredSmith the example you showed clarify my mistake – NashPL Apr 26 '18 at 14:32

2 Answers2

1

That's because you are returning inside your callback. Try to use a Promise or add a callback parameter.

With a Promise

/**
 * A functio which writes a data into a file
 * @param  {[string]} fileName A file location with file name string
 * @param  {[string]} msg      A data to be saved
 * @return {[object]}          A response object with response code and msg.
 */
static toFile(fileName, msg) {
    return new Promise(resolve => {
        fs.appendFile(fileName, msg, function(err) {
            let responseObject = {};
            if (err) {
                responseObject.status = 500;
                responseObject.msg = 'Error occured please view ' + fileName;
            } else {
                responseObject.status = 200;
                responseObject.msg = 'Success, file has been created ' + fileName;
            }
            resolve(responseObject);
        });
    });
}

toFile('myfile.txt', 'Hello world!')
    .then(data => {
        console.log(data); // will print responseObject
    });

With a callback function

/**
 * A functio which writes a data into a file
 * @param  {[string]} fileName A file location with file name string
 * @param  {[string]} msg      A data to be saved
 * @return {[object]}          A response object with response code and msg.
 */
static toFile(fileName, msg, cb) {
    fs.appendFile(fileName, msg, function(err) {
        let responseObject = {};
        if (err) {
            responseObject.status = 500;
            responseObject.msg = 'Error occured please view ' + fileName;
        } else {
            responseObject.status = 200;
            responseObject.msg = 'Success, file has been created ' + fileName;
        }
        cb(responseObject);
    });
}

toFile('myfile.txt', 'Hello world!', function(response) {
    console.log(response); // will print your responseObject
});
Eric Ly
  • 2,095
  • 1
  • 20
  • 27
1

here the problem is the way that the fs.appendFile function works. the function is asynchronous.... so basically you can see your function as the following:

static toFile(fileName, msg) {
    fs.appendFile(fileName, msg, function(err) {
        let responseObject = {};
        if (err) {
            responseObject.status = 500;
            responseObject.msg = 'Error occured please view ' + fileName;
            return responseObject;
        }
        responseObject.status = 200;
        responseObject.msg = 'Success, file has been created ' + fileName;

        return responseObject; //this wont be assigned to anything.
    });
    return undefined; //this is why you get undefined 
}

you can use 2 approachs:

Callback approach: this will trigger your cb function when you get the response obj.

static toFile(fileName, msg, cb) { //cb is a function
    fs.appendFile(fileName, msg, function(err) {
        let responseObject = {};
        if (err) {
            responseObject.status = 500;
            responseObject.msg = 'Error occured please view ' + fileName;
            return responseObject;
        }
        responseObject.status = 200;
        responseObject.msg = 'Success, file has been created ' + fileName;

        cb(responseObject); //instead of returning, call your cb function and use it as you please.
    });
}

Promise approach

this will return the response object when resolves, of course you have to handle a promise outside the toFile function.

   static toFile(fileName, msg) { //cb is a function
    return new Promise((resolve, reject) => {
            fs.appendFile(fileName, msg, function(err) {
                let responseObject = {};
                if (err) {
                    responseObject.status = 500;
                    responseObject.msg = 'Error occured please view ' + fileName;
                    reject(responseObject)
                }
                responseObject.status = 200;
                responseObject.msg = 'Success, file has been created ' + fileName;

                resolve(responseObject)
            });
        }
    }
Prince Hernandez
  • 3,623
  • 1
  • 10
  • 19