guicalmeida
guicalmeida

Reputation: 63

method that uses data retrieved from an observable on its own component returns undefined when used as Input()

I created a template example.component.html that receives a method as a variable to its click action:

<div>
  <button (click)="method()">click here</button>
</div>

on the example.component.ts file, the method comes from an input(), so I can use this template on multiple situations:

@Component({
  selector: 'example',
  templateUrl: './example.component.html',
})
    export class ExampleComponent implements OnInit {
      @Input() method;
    
      constructor() {}
    
      ngOnInit(): void {}
    }

Here's where it gets complicated. At the parent component, the method that will be triggered on click uses a variable coming from an observable:

parent-example.component.html

  <example [method]="onClick"></example>

parent-example.component.ts

@Component({
  selector: 'parent-example',
  templateUrl: './parent-example.component.html',
})
export class ParentExampleComponent implements OnInit {
  @Input() method;
  business;

  constructor(businessEntityService: BusinessEntityService) {
    businessEntityService.entities$.subscribe(
      data => (this.business = data),
    );
  }

  onClick() {
    console.log(this.business);
  }

  ngOnInit(): void {}
}

Even though the parent component is subscribing businessEntityService observable and I've check it has in fact data, when I click the button, the console logs undefined.

I understand this probably has to do with scope and the stack is looking for this.business at the children component, however I would love to know if there's anyway to call a method that uses a variable from a subscription from its own component as Input().

Upvotes: 2

Views: 42

Answers (1)

Drenai
Drenai

Reputation: 12367

The this context is being lost (I think). Can happen when passing class methods as params

Replace the ParentExampleComponent#onClick method with:

onClick = () => {
    console.log(this.business);
}

Note: behind the scenes, Typescript will now treat onClick as a class property, and moves that code into the constructor. Using an arrow function locks the this context of that function

Upvotes: 2

Related Questions