0

I created some javascript functions that read and write to a json file, are suppose to be invoked in angular(from typescript code), using jsonfile library. Here is the code:

function savePatient(patient){
    const jsonfile = require('jsonfile')
    const file = 'src/resources/patients.json'
    jsonfile.writeFile(file, patient, {flag: 'a'}, function(err){
        if(err) console.error(err)
    })
}

function getPatients(){
    const jsonfile = require('jsonfile')
    const file = 'src/resources/patients.json'
    jsonfile.readFile(file, function(err, obj){
        if(err) console.error(err)
        console.dir(obj)
        return obj
    })
}

Here is the declaration of functions in Angular component:

declare function savePatient(patient: Patient);
declare function getPatients(): Patient[];

I managed to successfully call the savePatient() function, and it does as intended.

When I try to invoke console.log(getPatients()) from inside the Angular component, the output is undefined, but the getPatients() function itself generates a correct console output from the console.dir(obj) line.

How am I suppose to get the correct value of the function inside the Angular component?

Also, this project is inside an electron container, if someone may find that relevant.

I found it interesting that the Angular component is the first one to output information to console, even though it would make sense that the js functions should give output before it, considering that the Angular component should be dependent on the return value of the js function, but I don't know what to make of that.

kulijana
  • 55
  • 8
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Heretic Monkey May 20 '19 at 17:50
  • `readFile` is asynchronous. Therefore `getPatients` has to asynchronously return the data within it. You can do that with Promises or callback functions, as explained in the answers to the duplicate. – Heretic Monkey May 20 '19 at 17:52

2 Answers2

1

Your function

function getPatients(){
    const jsonfile = require('jsonfile')
    const file = 'src/resources/patients.json'
    jsonfile.readFile(file, function(err, obj){
        if(err) console.error(err)
        console.dir(obj)
        return obj
    })
}

works asynchronous (see docs).

You have two options. The first one is to handle the file-reading asynchronously:

function getPatients(){
    const jsonfile = require('jsonfile')
    const file = 'src/resources/patients.json';
    // Create a new promise
    return new Promise((resolve, reject) => {
        jsonfile.readFile(file, function(err, obj){
            if(err){
                console.error(err)
                return reject(err);
            }
            console.dir(obj)
            return resolve(obj);
        });
    });
}

...

// Prints the read object in the console, after the file reading is done
getPatients().then((obj) => {
    console.dir(obj);
});

The second options, and in my opinion the best solution for you is using the synchronous way to read a file:

function getPatients(){
    const jsonfile = require('jsonfile')
    const file = 'src/resources/patients.json'
    try {
        const obj = jsonfile.readFileSync(file);
        console.dir(obj);
        return obj;
    } catch(e) {
        console.error(e);
    });
}
Batajus
  • 5,831
  • 3
  • 25
  • 38
0

Please make sure that your function return something. In this snippet i added a return statement before jsonfile.readfile().

function getPatients(){
  const jsonfile = require('jsonfile')
  const file = 'src/resources/patients.json'
  return jsonfile.readFile(file, function(err, obj){
      if(err) return err;
      return obj;
  });
}
ilyas shabi
  • 194
  • 1
  • 7
  • this doesn't look any different from the code that was posted other than removing a logging message and adding a few semicolons.... how does this solve the problem the poster is asking about, exactly? I realize there is another change, but it's not obvious what that is, or how it affects anything, and so the answer could use some explanation. – Claies May 19 '19 at 23:07
  • it's normal to receive an undefined from a function that don't have a RETURN statement, so i added return to solve the problem. You can also use: jsonfile.readFile(file).then(...) and return inside then – ilyas shabi May 19 '19 at 23:13
  • right, I understand that there is a return statement missing, but you didn't make that clear in the question..... You should really consider updating the question to be something more than just a block of mostly the same code. – Claies May 19 '19 at 23:22
  • Ok you're right, i'll update the answer now. thank youu – ilyas shabi May 19 '19 at 23:39
  • I tried adding the missing return statement, but the problem persists, with the same output as previously. On a side note, I sort of evaded this problem due to the fact that Angular 7 has a new way of reading json files that is far easier. – kulijana May 20 '19 at 09:21