I am attempting to implement the singleton design pattern by using a shared service so that all components are able to receive the updated global variable provided by the service.
The result is that it will update without issue when called from app component, but no component receives the value when subcribing to:
colorString$ = this.colorSource.asObservable();
The method used to subscribe which is not returning a value:
constructor( private sharedSer : SharedColorService ) {
sharedSer.Update(this.myColor);
}
This is the service:
import {Injectable} from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class SharedColorService {
// Observable string source
private colorSource = new Subject<string>();
// Observable string stream
colorString$ = this.colorSource.asObservable();
// Service message commands
Update(input:string) {
this.colorSource.next(input);
console.log("Service Color: " + input);
}
}
This is the app.component:
import { Component, OnInit } from '@angular/core';
import {SharedColorService} from './sharedColor.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
colors = ["#31b0d5", "#d55631", "#d531b0", "#31d556"]
myColor = this.colors[Math.floor(Math.random()*this.colors.length)];
constructor( private sharedSer : SharedColorService ) {
console.log("I can log");
console.log("App Color: " + this.myColor);
sharedSer.Update(this.myColor);
}
}
This is the component which the app component loads:
app.component.html:
<h1>APP: {{myColor}}</h1>
<app-navigation></app-navigation>
navigation.component
import { Component, OnInit, Injectable } from '@angular/core';
import {SharedColorService} from '../sharedColor.service';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.css'],
})
export class NavigationComponent{
myColor: string;
errors;
constructor(private _sharedService: SharedColorService){
console.log("I AM TRYING TO SUBSCRIBE");
this._sharedService.colorString$.subscribe(
result => {
console.log('Navigation received result: ', result);
this.myColor = result;
});
console.log('Navigation after subscribe: ', this.myColor)
}
}
And finally I have a router outlet, which loads from navigation:
navigation.component.html
<a class="col-sm-2" routerLink="/about" routerLinkActive="active">About</a>
<router-outlet></router-outlet>
about.component
import { Component, OnInit } from '@angular/core';
import {SharedColorService} from '../sharedColor.service';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {
myColor: string;
constructor(private _sharedService: SharedColorService){}
ngOnInit() {
this._sharedService.colorString$.subscribe(
data => {
this.myColor = data;
console.log("About received color: " + this.myColor + " Data: " + data );
});
}
}
The output of console with all of the logging when loading the page is:
I can log
app.component.ts:15 App Color: #31d556
sharedColor.service.ts:16 Service Color: #31d556
navigation.component.ts:15 I AM TRYING TO SUBSCRIBE
navigation.component.ts:21 Navigation after subscribe: undefined
When accessing about, it is not called to subscribe either - I don't yet understand the lifecycle of the router outlet regarding OnInit and its constructors.
Subject
won't replay old values to new subscribers. – jonrsharpe