I\'m trying to execute a function from another component (These 2 components are NOT siblings). My guess is that I will need to use @Output and even
I agree that your idea regarding a service with an observable is your best option here (as others have suggested) - although I'd prefer a BehaviorSubject
in this case. Here's a simple, working plunkr demonstrating how you could implement this:
https://plnkr.co/edit/quHc2yOkxXIbXYUlnZbB?p=preview
If we break down the requirement, what you need here is an Event Proxy service that just passes on the event. This plunkr is also able to also pass a parameter object via the service - in case you need to do this - but if not then just pass any object you want (or just remove the param
arguments from all the methods entirely).
This implementation doesnt care that the components are not siblings - because we're using a service. Both will be provided with the same service instance regardless of the structure of your app.
For quick reference, here are the pieces of code that matter:
EventProxyService
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class EventProxyService {
private eventSubject = new BehaviorSubject(undefined);
triggerSomeEvent(param: any) {
this.eventSubject.next(param);
}
getEventSubject(): BehaviorSubject {
return this.eventSubject;
}
}
FirstComponent
import { Component, OnInit } from '@angular/core';
import { EventProxyService } from './event-proxy.service';
@Component({
selector: 'app-first',
templateUrl: './src/first.component.html'
})
export class FirstComponent implements OnInit {
displayText = 'I havent created any events yet.';
constructor(private eventProxyService: EventProxyService) { }
ngOnInit() { }
triggerAnEvent() {
this.eventProxyService.triggerSomeEvent(Date());
this.displayText = 'I fired an event.'
}
}
SecondComponent
import { Component, OnInit } from '@angular/core';
import { EventProxyService } from './event-proxy.service';
@Component({
selector: 'app-second',
templateUrl: './src/second.component.html'
})
export class SecondComponent implements OnInit {
displayText = 'I havent got an event yet';
constructor(private eventProxyService: EventProxyService) { }
ngOnInit() {
this.eventProxyService.getEventSubject().subscribe((param: any) => {
if (param !== undefined) {
this.theTargetMethod(param);
}
});
}
theTargetMethod(param) {
this.displayText = 'Target Method got called with parameter: "' + param + '"';
}
}