Andi Giga
Andi Giga

Reputation: 4182

Angular 5: Service Getter Why Double Arrow if Referenced to Getter instead of Calling Getter Directly

I have a service which is loading basic system information which I want to share between several components.

If I make a getter method this in the getter becomes the component's this if I not use double arrows in the service.

service

import { Injectable } from '@angular/core';

@Injectable()
export class WhoAmIService {

  constructor() { }
  whoAmI = 'I\'m a service'
  getterOne(): string {
    return this.whoAmI
  }
  getterTwo = (): string => {
    return this.whoAmI
  }  

}

component

import { Component } from '@angular/core';
import { WhoAmIService } from './who-am-i.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  whoAmI = 'I\'m a component'
  getterOne: Function
  getterTwo: Function
  constructor(
    private whoAmIService: WhoAmIService
  ) {
    this.getterOne = whoAmIService.getterOne
    this.getterTwo = whoAmIService.getterTwo
    console.log('cool', whoAmIService.getterOne())
    console.log('cool', whoAmIService.getterTwo())
    console.log('why is this different', this.getterOne())
    console.log('cool', this.getterTwo())    
  }
}

https://stackblitz.com/edit/angular-xxsven

Question

Why do I need the arrow function if I assign the getter function to the component?

Upvotes: 3

Views: 57

Answers (2)

Sunil
Sunil

Reputation: 11243

Whenever function is assigned to any other variable, actually copies the function definition and act as new function which has the same codes.

You can think as it is clone of the original function.

Now important point is the context where this function is getting executed. So this is nothing but the context where is it being executed.

Now lets come back to your example

  1. whoAmIService.getterOne() - this getting executed on inside the whoAmIServiceso the context (this) point to whoAmIService.
  2. this.getterOne() - Here this will point to AppComponent class since the context is AppComponent.

Note : This is nothing to do with Angular. Its Javascript concept.

Just visit this for more info - https://hackernoon.com/execution-context-in-javascript-319dd72e8e2c

Upvotes: 1

SiddAjmera
SiddAjmera

Reputation: 39462

For normal function syntax, the scope of this generally changes resulting in unexpected behavior. That's what's happening in your case.

The newer Arrow Function syntax fixes this issue by retaining the scope of this. That's why you can simply rely on it to make it work and show the expected behavior.

If you still want to make it work using the old function syntax, you'll have to bind the service instance as shown below:

console.log('why is this different', this.getterOne.bind(this.whoAmIService)());

Here are a few articles and SO OPs for your ref:

  1. Lambda functions vs bind, memory! (and performance)
  2. Arrow Functions: MDN

Here's your Updated StackBlitz for any ref.

Upvotes: 1

Related Questions