Invoke function in child component using a service injected in parent

Issue

I have a function using a service call that must be invoked in both parent and child component.

@Component({
  selector: 'my-app',
  template: `
    <app-child [callTheObservable]="callTheObservable"></app-child>
    <button (click)="callTheObservable()">button</button>
  `,
  styleUrls: ['./parent.component.css'],
})
export class ParentComponent {
  constructor(private customService: CustomService) {}

  callTheObservable() {
    this.customService.anObservable.subscribe((res) => {
      console.log(res);
    });
  }
}

Child component gets the function through Input but when function is called, the service is not recognized.

export class ChildComponent implements OnInit {
  @Input() callTheObservable: () => void;

  constructor() {}

  ngOnInit() {
    this.callTheObservable();
  }
}

Error: Cannot read properties of undefined (reading 'anObservable')

I had to inject the service to get recognized but now I have a service that is never used.

constructor(private customService: CustomService) {}

An easy way to achieve it is by emitting an event but I was wondering if I could make it by Input but without injecting the service in child component?

The problem is solved when injecting the service in child component because of singleton service, so both in parent and child we inject the same reference?

Here is Stackblitz code

Solution

Normal functions do not maintain their original lexical context, so referring to this inside the function refers to whatever object the function is executing inside.

Arrow functions do maintain their original lexical context, so referring to this inside the function will refer to the original this when the function was defined.

So just make it an arrow function.

export class ParentComponent {
  constructor(private customService: CustomService) {}

  callTheObservable = () => {
    this.customService.anObservable.subscribe((res) => {
      console.log(res);
    });
  }
}

Answered By – Chris Hamilton

Answer Checked By – Senaida (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.