I have done this multiple times in my App. It's simple, it should work... But this time it doesn't.
My issue:
I am calling a method in a service from a Component A, my Component B is subscribed but doesn't react nor receive anything. subscribe()
is not triggering!
navigation-elements.service.ts
@Injectable()
export class NavigationElementsService {
updateIBOsNavigation$: Observable<any>;
private updateIBOsNavigationSubject = new Subject<any>();
constructor() {
this.updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
}
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
}
IboDetailsGeneral
component
export class IboDetailsGeneral implements OnInit, OnDestroy {
id: string;
private sub: any;
constructor(private route: ActivatedRoute, private iboService: IBOsService, private navigationService: NavigationElementsService) {
this.sub = this.route.params.subscribe(params => {
this.id = params['id'];
console.log('CALLING updateIBOsNavigation FUNCTION');
this.navigationService.updateIBOsNavigation(this.id);
});
}
ngOnInit() {
console.log('CALLING updateIBOsNavigation FUNCTION AGAIN');
this.navigationService.updateIBOsNavigation('test');
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
This component triggers the service's method: updateIBOsNavigation
.
IBOsNavigationElement
component
export class IBOsNavigationElement implements OnInit {
private id: string;
constructor(private navigationService: NavigationElementsService) {
this.navigationService.updateIBOsNavigation$.subscribe((navigationData) => {
log.d('I received this Navigation Data:', JSON.stringify(navigationData));
this.id = navigationData;
}
);
}
ngOnInit() {
}
}
This component is subscribed, it should listed and receive the data...
Let's sort out DI:
Take into account that IboDetailsGeneral
is in a lower layer on the App's structure, so IboDetailsGeneral
is child of IBOsNavigationElement
.
This is why I add NavigationElementsService
into IBOsNavigationElement
's module:
NavigationModule
is IBOsNavigationElement
's module
@NgModule({
imports: [
// A lot of stuff
],
declarations: [
// A lot of stuff
IBOsNavigationElement
],
exports: [
// A lot of stuff
],
providers: [
NavigationElementsService
]
})
Console:
CALLING updateIBOsNavigation FUNCTION
updateIBOsNavigation "95"
CALLING updateIBOsNavigation FUNCTION AGAIN
updateIBOsNavigation "test"
This console results tells me that:
- The method is being called, so no provider error. Communication with service is OK.
My tests:
- I have tried calling a random method in
IBOsNavigationElement
(the listener), and communication with service is good. - The only place where
NavigationElementsService
is added toproviders
is inNavigationModule
, so there is only one instance of the service right? Then, the issue explained in the following link doesn't take place: Angular 2 observable subscription not triggering
I am really sorry for my 'wall of text' but at this point I am kind of desperate.
Any help is appretiated, thank you!
Update 1:
After the first answer I have tried several things...
Using ReplaySubject
:
@Injectable()
export class NavigationElementsService {
public updateIBOsNavigation$ = new ReplaySubject();
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigation$.next(navigationData);
}
}
Result: When calling updateIBOsNavigation()
, subscribe()
is still not triggering.
Using BehaviorSubject
:
@Injectable()
export class NavigationElementsService {
updateIBOsNavigationSubject = new BehaviorSubject<any>('');
updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
}
Result: It enters subscribe()
on initialization but when I call updateIBOsNavigation()
, subscribe()
is still not triggering.
Using BehaviorSubject
v2:
I tried this approach: behaviourSubject in angular2 , how it works and how to use it
@Injectable()
export class NavigationElementsService {
public updateIBOsNavigation$: Subject<string> = new BehaviorSubject<string>(null);
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigation$.next(navigationData);
}
}
Result: Same as previous application of BehaviorSubject
.
Update 2:
More samples of desperate attempts after researching throughout the web...
Using BehaviorSubject
v3:
@Injectable()
export class NavigationElementsService {
updateIBOsNavigation$: Observable<any>;
updateIBOsNavigationSubject = <BehaviorSubject<any>> new BehaviorSubject([]);
constructor() {
this.updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
}
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation()', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
}
Result: Same as previous BehaviorSubject
attempts... Desperation is rising...
Update 3:
Just in case, I wanted to make sure that NavigationElementsService
is a singleton:
export class NavigationModule {
static forRoot() {
return {
ngModule: NavigationModule,
providers: [NavigationElementsService]
};
}
}
And when importing:
imports: [
NavigationModule.forRoot()
]
Result: Same issue as always, subscribe()
not triggering, but at least I know that there is one instance of NavigationElementsService
.