I'm facing a challenge where I want to subscribe to an observable within a service. The catch is, I also need to utilize the AlertService
to display error messages. Essentially, I have a service within another service, which seems to be causing a circular dependency issue.
Let's take a closer look at the AlertService:
@Injectable()
export class AlertService {
private subject = new Subject<any>();
private keepAfterNavigationChange = false;
constructor(private router: Router) {
router.events.subscribe(event => {
if (event instanceof NavigationStart) {
if (this.keepAfterNavigationChange) {
this.keepAfterNavigationChange = false;
} else {
this.subject.next();
}
}
});
}
success(message: string, keepAfterNavigationChange = false) {
this.keepAfterNavigationChange = keepAfterNavigationChange;
this.subject.next({ type: 'success', text: message });
}
error(message: string, keepAfterNavigationChange = false) {
this.keepAfterNavigationChange = keepAfterNavigationChange;
this.subject.next({ type: 'error', text: message });
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
The AlertService is transformed into a Mat Snackbar
on the AlertComponent
. The snackbar is then rendered on various other components.
export class AlertComponent implements OnInit {
message: any;
constructor(private alertService: AlertService, public snackBar: MatSnackBar) { }
ngOnInit() {
this.alertService.getMessage().subscribe(message => {
if (message != null) {
if (message.type === 'error') {
this.snackBar.open(message.text, undefined, { duration: 8000, verticalPosition: 'bottom', panelClass: ['snackbar-error'] });
} else if (message.type === 'success') {
this.snackBar.open(message.text, undefined, { duration: 8000, verticalPosition: 'bottom', panelClass: ['snackbar-success'] });
} else {
this.snackBar.open(message.text, undefined, { duration: 8000, verticalPosition: 'bottom' });
}
}
});
}
}
I have successfully subscribed inside components like this:
export class AboutComponent implements OnInit {
ngOnInit() {
this.emailService.sendEmail('example@example.com')
.subscribe(code => {
console.log(code);
this.alertService.success('Thanks for your message!');
}, error => {
this.alertService.error('Error sending message.');
}
);
}
}
@Injectable()
export class EmailService {
constructor(private http: HttpClient) { }
sendEmail(email: Email) {
return this.http.post(BACKEND_URL + 'send', email);
}
}
However, I am now attempting to subscribe inside the service because EmailService
will be utilized in multiple components. How can I achieve this desired functionality?