Home > Software design >  TypeError: Cannot read properties of undefined
TypeError: Cannot read properties of undefined

Time:09-16

Working in Angular 12 and experiencing an error when I attempt to call a method within another method. Here's an abstraction of what I'm dealing with (in TypeScript as I am in Angular

export class SomeClass {

  testvariable

  onTaskCompleted(results) {
    if (!results) {
      return;
    } else {
      //The line below works
      console.log(results);
      //The line below throws and error
      this.drawSomething(results)
      //In fact any reference to something outside of this function throws an error
      this.testvariable = results
    }
  }

  //The unique thing about OnTaskCompleted is that it is also used as a callback handler by a 3rd party library which is throwing the error
  //It is called in another function like so.  It is producing the correct result in onTaskCompleted, but breaks when I do something like above
  this.something.onResults(this.onResults);

  drawSomething(results) {
    if (!results) {
      return;
    } else {
      //perform some work
    }
  }
}

}

When I run this I get a TypeError: Cannot read properties of undefined. If I include the doSomethingElse function in any of the other functions defined in my class I have no issue and it works as expected. The only other thing of note is that the function where I'm having this issue doSomething() is used as a callback by an external library and that seems to be what is throwing the error whenever I include any reference to something 'outside' of doSomething in the doSomething function. Any thoughts would be appreciated

CodePudding user response:

the function where I'm having this issue doSomething() is used as a callback

You're most likely passing the function like this:

library.externalFunction(this.doSomething);

Which is a problem because this parameter is set to the caller, i.e. it will not be the class instance anymore. If doSomething() tries to access a property on this, it will be an error.

One correct way of writing this would be:

library.externalFunction(param => this.doSomething(param));

Arrow functions capture this and behave more like what you'd expect them to behave.

Alternatively, one could explicitly bind this on the function:

library.externalFunction(this.doSomething.bind(this));

There are quite a few answers here that explain function scoping, e.g. https://stackoverflow.com/a/20279485

  • Related