angularservicerxjscomponentsevent-bus

Angular - exchange data of two components over BehaviorSubject


I have the following service with a BehaviorSubject to exchange data from component A to component B:

export class TimeconfirmationafterchangeService {   

data: BehaviorSubject<any> = new BehaviorSubject<any>(null);

constructor() {
  }
}

component A set the data like this:

timeconfirmationafterchange(scheduleIntervalContainersToConfirm: 
Array<Array<ScheduleContainer>>, scheduleIntervalContainers: 
Array<ScheduleContainer>, index: number) {
   let data = {
     institution: this.institution,
     index: index,
     scheduleContainers: scheduleIntervalContainers,
     scheduleIntervalContainersToConfirm: scheduleIntervalContainersToConfirm
    }
 this.timeconfirmationafterchangeService.data.next(data);
 this.route.navigate(['app/tabs/timeconfirmationafterchange']);
}

and component B uses it like this:

this.timeconfirmationafterchangeService.data.subscribe(timeConfirmationResponse => {
...

This all works fine. My question now woud be if there is any possibility for component B to invoke a function or send an event to component A, maybe over the timeconfirmationafterchangeService service?


Solution

  • You have to use an Event Bus using a subject, we can use two properties, one is EventName which is used to filter out specific actions (where there are multiple listeners) another property is data, which can be used to transfer data.

    export class TimeconfirmationafterchangeService {   
        data: BehaviorSubject<any> = new BehaviorSubject<any>(null);
        sub: Subject<any> = new Subject<any>();
        subObservable$!: Observable<any>;
        constructor() {
            this.subObservable$ = this.sub.asObservable();
        }
    
        emit(eventName: string, data = {}) {
            this.sub.next({eventName, data});
        }    
    }
    

    Then from child component we trigger the emit.

    someMethod() {
        this.timeconfirmationafterchangeService.emit('parentEvent', {test: 1});
    }
    

    On the parent we subscribe to the observable to receive events, we must unsubscribe the listener on destroy of component using subscription to prevent memory leaks.

    export class ParentComponent {
        private subscription: Subscription = new Subscription();
    
        ngOnInit() {
            this.timeconfirmationafterchangeService.subObservable$.subscribe((event: any) => {
                if(event.eventName === 'parentEvent') {
                    this.someMethodCall(event.data);
                }
            });
        }
    

    Working demo below showing the working of event bus.

    Stackblitz Demo