Home > Back-end >  this returns undefined: (node:3196) UnhandledPromiseRejectionWarning: TypeError: Cannot read propert
this returns undefined: (node:3196) UnhandledPromiseRejectionWarning: TypeError: Cannot read propert

Time:12-07

Here's my code:

https://github.com/DavidNyan10/NewProject

const fs = require('fs');
const csv = require('csv-parser')

const myString = new Promise((resolve, reject) => {
    resolve('John');
});

class myClass{
    constructor(filename){
        this.myArray = [];
        this.myArray.push(new Promise((res) => {
            fs.createReadStream('filename')
                  .pipe(csv(['FirstName', 'LastName', 'Address', 'Town', 'Country', 'Postcode']))
                  .on('data', (data) => {
                    return(data);
                  })
          }))
    }
    async myFunction() {
        for(let i = 0; i < this.myArray.length; i  ) {
            if (myString.includes(this.myArray[i]['phrase'])){
                if (this.cooled_down(i)){
                    this.approve(i, myString);
                }
            }
        }
    }
    
    cooled_down(i){
        dictionary = this.myArray[i]
        if (!dictionary.keys().includes('approved')){
            // Means we have never approved on this person!
            return True;
        } else{
            now = datetime.now();
            duration = now - datetime.fromtimestamp(dictionary['approved']);
            duration_seconds = duration.total_seconds();
            hours = divmod(duration_seconds, 3600)[0];
            if (hours >= 24){
                return True;
            } else{
                console.log("Couldn't approve "   dictionary['FirstName']   "Cool Down time: "   24 - hours);
            }
        }
        return False;
    }

    approve(i, myString){
        dictionary = this.myArray[i];
        try{
            setTimeout(function(){
                console.log(myString);
                console.log(dictionary['FirstName'])
                console.log(dictionary['Postcode'])
            }, 60 * 60 * 3);
        }catch(e){
            console.log(e);
        }

        now = datetime.now();
        this.myArray[i]['approved'] = now.timestamp();
    }
}

myObj = new myClass("myCSV.csv");
myString.then(myObj.myFunction);

It keeps saying

(node:3196) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'myArray' of undefined
    at myFunction (D:\projects\newproject\index.js:20:30)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3196) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:3196) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

But as you can clearly see, this.myArray is clearly defined well on line 10.

What is going on?

I'm pretty new to javascript classes and objects, so I'm sorry if I looks dumb.

Also, any ideas how i can make line 11-17 better? I'm just putting the csv into an array but I don't know if that's the best way to do it.

CodePudding user response:

You called myString.then(myObj.myFunction). This is changing this keyword from myObj to something else. If you want to keep the context of the this keyword you need to bind this manually or call the function instead of passing it into then callback. Example:

// Binding `this` to object:
myString.then(myObj.myFunction.bind(myObj));

// or
// Calling the function inside anonymous function instead 
// of passing it to `then` callback:
myString.then(() => myObj.myFunction());
  • Related