Reputation:
I currently have something like this in the footer component of my project
ngOnInit() {
const checkLocalStorage = interval(15000);
checkLocalStorage.subscribe(data => {
// code for checking the Localstorage
});
}
I don't like the idea of having timers looping to check for changes every so many seconds.
I need a simple, clean way to communicate messages to other components (non related component).
I know about RxStore is complicated.
I there a simple way to send a simple message to another component telling it to run a method in it's component?
How can I do this without using interval or other loop?
Upvotes: 0
Views: 38
Reputation: 1827
Simplest way is to use HTML CustomEvents
Listen to event:
document.addEventListener('my-event', () => {
console.log('My event !');
});
Dispatch event:
document.dispatchEvent( new CustomEvent('my-event') );
Upvotes: 0
Reputation: 336
Use this event services, to communicate between components.
import { Injectable } from '@angular/core';
import { Subject, Observable, Subscription } from 'rxjs';
const ServiceName: string = "Events Service";
@Injectable()
export class EventsService implements IEventsService {
private events = { };
constructor() { }
public subscribe(event: string): Observable<any>;
public subscribe(event: string, callback: (value: any) => void): Subscription;
public subscribe(event: string, callback: (value: any) => void, error: (error: any) => void): Subscription;
public subscribe(event: string, callback: (value: any) => void, error: (error: any) => void, complete: () => void): Subscription;
public subscribe(event: string, callback?: (value: any) => void, error?: (error: any) => void, complete?: () => void) {
if (!event) {
throw new Error(`[${ServiceName}] => Subscription method must get event name.`);
}
if (this.events[event] === undefined) {
this.events[event] = new Subject<any>();
}
if (typeof callback !== 'function') {
return this.events[event].asObservable();
} else {
return this.events[event].asObservable().subscribe(callback, error, complete);
}
}
public publish(event: string, eventObject?: any) {
if (!event) {
throw new Error(`[${ServiceName}] => Publish method must get event name.`);
} else if (!this.events[event]) {
return;
}
this.events[event].next(eventObject);
}
}
export interface IEventsService {
publish(event: string, eventObject?: any);
subscribe(event: string): Observable<any>;
subscribe(event: string, callback: (value: any) => void): Subscription;
subscribe(event: string, callback: (value: any) => void, error: (error: any) => void): Subscription;
subscribe(event: string, callback: (value: any) => void, error: (error: any) => void, complete: () => void): Subscription;
}
interface ISubscribe{
(event: string): Observable<any>;
(event: string, callback: (value: any) => void): Subscription;
(event: string, callback: (value: any) => void, error: (error: any) => void): Subscription;
(event: string, callback: (value: any) => void, error: (error: any) => void, complete: () => void): Subscription;
}
How to use this service :
publish event from XYZ component
publishNewEvent(){
this.eventsService.publish("PROFILE_UPDATED");
}
subscribe to an event in ABC component
constructor(private eventsService: EventsService){
this.eventsService.subscribe("PROFILE_UPDATED", () => {
console.log("Called");
});
}
Upvotes: 1
Reputation: 2496
That is what Angular's Component Interaction is made for. Using @Input
to pass data into a component and @Output
to notify a parent about a childs event.
If you have an app structure that makes this too complicated, you would want to think about using Redux.
If that is too complicated or over-engineered for this you can write a simple service. This service should provide an Observable
which your footer component subscribes to. From the other component now run a function in the service which delivers the next value in the Observable
.
Upvotes: 1