As per Software Engineering prospective, identify the problem first, then think of the solution within the scope of design patterns, but also take in consideration the framework. In the mentioned scenario; the Observer Pattern is what you are looking for.
We need to communicate between components that might or might not be located within the same module
which also might have a parent-child or child-parent relationship, or might be brothers-relationship or might not have a relationship at all! So the generic solution is to created a Service
.
Now according to your use case, you're calling it as if you have this one only functionality in which you want to observe this button to toggle the sidenav, but from my own point of view, it's better to create a more generic form of usage in which is defined as "Communication". This will make your service reusable and can do many other things than just observing a button.
I'll add some code to demonstrate.
First of all we've got the communication.service.ts
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
@Injectable({
providedIn: 'root', // Singleton
})
export class ComunicationService {
private subject: Subject<any>;
private observable$: Observable<any>;
constructor() {
this.subject = new Subject();
this.observable$ = this.subject.asObservable();
}
sendData(data: any) {
this.subject.next(data);
}
clearData() {
this.subject.next();
}
getData(): Observable<any> {
return this.observable$;
}
}
Now in the header.component.ts
for example we need to use DI
design pattern to inject this service and use it to sendData
.
export class HeaderComponent {
constructor(private communicationService: CommunicationService) {}
onButtonClick() {
this.communicationService.sendData(ANYTHING_YOU_WANT_TO_SHARE);
}
}
And in your sidenav.component.ts
export class SidenavComponent {
constructor(private comunicationService: CommunicationService) {
this.listenToButtonClicks(); // Never forget to call the subscribing function in the constructor, and unsubscribe OnDestroy to prevent memory leak
}
listenToButtonClicks() {
this.communicationService.getData().subscribe((res) => {
console.log(res); // Check if you're getting the data
// Do whatever you need to do here with the shared data
this.toggleSidenave(); // Call the function that toggles the Sidenav
})
}
}
And we're done!
Now what makes BehaviorSubject
special is that it can be initialized with an initial value (To indicate that sidenav is closed by default for example).
You can learn more about BehaviorSubject
here
Hope this helped & Happy coding!