0

I'm using angular 8 and here's my code.

export class AppComponent {

  public auth2: gapi.auth2.GoogleAuth = null;
  public signInStatus: string = "Unknown";

  constructor(private zone: NgZone, private httpClient: HttpClient) {}

  public ngAfterViewInit() {
    this.googleInit();
  }

  public googleInit() {

    // gapi javascript library is loaded in index.html file using
    // <script src="https://apis.google.com/js/client:platform.js"></script>
    // here I just use it
    gapi.load('auth2', () => {

      this.auth2 = gapi.auth2.init({
        client_id: '2xxxxxp.apps.googleusercontent.com',
        cookiepolicy: 'single_host_origin',
        scope: 'profile'
      });

      this.auth2.then( (googleAuth: gapi.auth2.GoogleAuth) => {

        let isSignedIn: boolean = googleAuth.isSignedIn.get();
        // if I use here debugger; then this referes to AppComponent
        // I come from javascript world, where 'this' refers to current scope
        // why does 'this' refere to AppComponent here?
        this.updateSignInStatus(isSignedIn);

      }, onFailure => {
          console.log("Initialization failed");
      });
    });
  }

  public updateSignInStatus(signedIn: boolean) {

    this.zone.run(() => {
      debugger;
      // I though that 'this' here referes to current scope which
      // is anonymous function. The same question as below
      this.signInStatus = signedIn ? "Yes" : "No";
    });
  } 

I want to understand why 'this' in anonymous functions refers to AppComponent. What have I missed. Perhaps some links to documentation.

enter image description here

broadband
  • 3,266
  • 6
  • 43
  • 73
  • `this.zone.run` keep the scope to the component – Jacopo Sciampi Dec 19 '19 at 13:11
  • You use an arrow function and those are lexically bound to the context they are defined in. Since you have the arrow function in (presumably) an `AppComponent` class, that's what the `this` context would be bound to. – VLAZ Dec 19 '19 at 13:11
  • Also relevant: [Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?](https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-exchangeable) – VLAZ Dec 19 '19 at 13:12
  • So if I use `function() {}` then `this` points to current anonymous function scope. – broadband Dec 19 '19 at 13:12
  • @broadband yes, normal functions will use the late context initialisation as normal. Arrow functions specifically go with lexical binding to avoid the very common problem of doing something like `doSomething(() => this.other())` where the expectation is that `this` will refer to the current context you're writing `doSomething()` in. – VLAZ Dec 19 '19 at 13:14
  • `this.zone.run(function (args) { debugger; // works: that has value of AppComponent that.signInStatus = "BLa"; // this is undefined this.signInStatus = signedIn ? "Yes" : "No"; });` Ok. – broadband Dec 19 '19 at 13:18
  • If `this` is `undefined`, then the callback is not executed with any context. I don't know what `zone.run` does, I'm just telling you what the rules of arrow and normal functions are in regards to context initialisation/binding. What do you expect `this` to be? You can also explicitly bind the context yourself, if needed. – VLAZ Dec 19 '19 at 13:21

0 Answers0