1

My function is

generateReport: function() {
          const copyFolder = (src, dest) => {
            return new Promise((res, rej) => {
                fsext.copySync(src, dest, (err, data) => {
                if (err) {
                  return rej(err);
                }
                return res(data);
              });
            });
          };

        const readFile = src => {
            return new Promise((res, rej) => {
                fs.readFile(src, (err, data) => {
                if (err) {
                    return rej(err);
                }
                return res(data);
                });
            });
        };

        copyFolder("./sample/", "./login/sample/" )
        .then(data => {
            return readFile("./sample/Duration_Suite.json", "utf8");
        })
        .then(data => {
        jsonData += data;
        console.log(jsonData)
        })  
    }

When I run this function, i am getting error

TypeError: Cannot read property 'then' of undefined

Please let me know where I am doing wrong

2
  • does fsext.copySync use a callback? the "Sync" part of its name indicates it probably doesn't Commented May 21, 2020 at 13:47
  • even if i give copy also same error @AlwaysLearning Commented May 21, 2020 at 13:50

2 Answers 2

1

When I use a mock version of copy and readFile the code works fine a long as there are proper callbacks being called. Try running the snippet below.

If you are getting Cannot read property 'then' of undefined that means that CopyFolder must be returning undefined, which doesn't seem possible since it returns a new Promise.

Is it likely that you call generateReport().then(...) and this is the reason for the error. Note that generateReport itself does not return a promise. It returns nothing at all which means undefined. To fix this you should return the promise that copyFolder returns. The second code snippet below does that and runs without the error.

Fist code snippet showing the problem

const fs = {
  copy: (s,d,cb) => cb(null, `copy data: ${s} ${d}`),
  readFile: (s,cb) => cb(null, `readFile ${s}`)
}
let callcount = 0;

const generateReport = () => {
  const copyFolder = (src, dest) => {
    return new Promise((res, rej) => {
      fs.copy(src, dest, (err, data) => {
        if (err) {
          return rej(err);
        }
        return res(data);
      });
    });
  };

  const readFile = src => {
    return new Promise((res, rej) => {
      fs.readFile(src, (err, data) => {
        if (err) {
          return rej(err);
        }
        return res(data);
      });
    });
  };

  // >>> BAD - no return statement here 
  copyFolder("./sample/", "./login/sample/")
    .then(data => {
      return readFile("./sample/Duration_Suite.json", "utf8");
    })
    .then(data => {
      console.log(`call #${++callcount}: ${data}`);
    });
};
console.log("First call without '.then'");
// first call will output data later since there are timeouts
generateReport();
console.log("Now call with '.then'");
// using .then after will give the error you see
generateReport().then(() => console.log("this fails"));

Second Snippet with Fix

const fs = {
  copy: (s,d,cb) => cb(null, `copy data: ${s} ${d}`),
  readFile: (s,cb) => cb(null, `readFile ${s}`)
}
let callcount = 0;

const generateReport = () => {
  const copyFolder = (src, dest) => {
    return new Promise((res, rej) => {
      fs.copy(src, dest, (err, data) => {
        if (err) return rej(err);
        return res(data);
      });
    });
  };

  const readFile = src => {
    return new Promise((res, rej) => {
      fs.readFile(src, (err, data) => {
        if (err) return rej(err);
        return res(data);
      });
    });
  };

  // >>> FIX - return copyFolder's promise
  return copyFolder("./sample/", "./login/sample/")
    .then(data => readFile("./sample/Duration_Suite.json", "utf8"))
    .then(data => console.log(`call #${++callcount}: ${data}`));
};
console.log("Call with '.then'");
generateReport().then(() => console.log("this worked!"));
console.log("This gets printed before the promise completes");

Sign up to request clarification or add additional context in comments.

Comments

1

it seems that fs.readFile expects callback as third parameter. Try use utils.promisify[link] to promisify it. Example

        .then(data => {
            const util = require('util');
            const readFilePromise = util.promisify(readFile);
            return readFilePromise("./sample/Duration_Suite.json", "utf8");
        })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.