Angular 2 can't call class function

孤人 提交于 2019-12-25 10:01:22

问题


inside my class I have a simple function that logs errors called logError(error);

I also use google maps api to grab latitude and longitude of an address, so all together this looks like this inside my exported class.

  //Log error
  logError(err) {
   console.error('Error: ' + err);
  }

  //Get Coordinates from address
  postcodeCoordinates(address: string, postcode: string) {
    var geocoder =  new google.maps.Geocoder();
    geocoder.geocode( { 'address': address + ', ' + postcode}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        console.log(results[0].geometry.location.lat() + " " +results[0].geometry.location.lng());
      } else {
       this.logError("Error " + status);
      }
    });
  }

The issue is that I get console error saying Uncaught TypeError: Cannot read property 'logError' of undefined , but this function works perfectly fine called in a same way from other places in the code, which makes me thing that this in this.logError("Error " + status); refferes to google maps api, instead of my class. How can I work around this? is there a way to achieve something like MyClassName.logError("Error") (Tried this, doesn't work)


回答1:


You should use an arrow function, the this keyword will the one for your component and not the one of the callback function. Something like that:

geocoder.geocode( { 'address': address + ', ' + postcode}, (results, status) => {
  if (status == google.maps.GeocoderStatus.OK) {
    console.log(results[0].geometry.location.lat() + " " +results[0].geometry.location.lng());
  } else {
   this.logError("Error " + status);
  }
});

In this case, logError is a method of your current class.

To give you more details, when using the this keyword in a function, it corresponds to the object the function is executed on:

// Example #1

function test() {
  console.log(this);
}

test(); // prints null

// Example #2

var obj2 = {
  test: function() {
    console.log(this);
  }
};

obj2.test(); // prints obj2

// Example #3

var obj3 = {
  test: function() {
    console.log(this);
  }
}

var fct3 = obj3.test;
fct3() // prints null!!

// Example #4

var obj4 = {
  test: function() {
    geocoder.geocode({ ... }, function(results, status) {
      console.log(this);
    });
  }
};

obj2.test(); // doesn't print obj2

When you provide a callback, it will be executed as a function outside any object as a context or with a specific context (and not the caller one). This means that inside your callback the this keyword corresponds to the context your callback is executed on and sure, it's not the component instance.

It's a common problem in JavaScript application. Arrow functions aren't classical functions and introduce the "lexical this" concept. This means that they don't use their own this but use the one from the caller:

var obj2 = {
  test: function() {
    geocoder.geocode({ ... }, (results, status) => {
      console.log(this);
    });
  }
};

obj2.test(); // prints obj2

This link could help you: https://toddmotto.com/es6-arrow-functions-syntaxes-and-lexical-scoping/. See the section: "Functionality: lexical scoping this".

Hope it helps you, Thierry



来源:https://stackoverflow.com/questions/34808369/angular-2-cant-call-class-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!