Am new to Angular2 but I have already made 30+ component and services and used Input, Output, ChangeDetectorRef, Pipes. So pretty much know about Angular2 by now. My app.component.ts looks like this
import { Component } from '@angular/core';
@Component({
selector: 'soc',
template: `
<header-block></header-block>
<router-outlet></router-outlet>
`,
})
export class AppComponent { }
As I need my header-block in every page so I added it outside router-block so I don't have to add it everywhere. Now the problem I am having is changing the value of variable in the header-block after doing an action in view inside router-outlet.
For example I have menu which will be visible to the user only after they login.
{{ user_is_logged }}
<ul class="nav navbar-nav navbar-right" *ngIf="user_is_logged == '1'">
<li><a href="#" (click)="logout($event)">Logout</a></li>
</ul>
user_is_logged is a variable whose value am getting from localStorage in header.block.component.ts
user_is_logged:string = localStorage.getItem("logged");
When the user is not logged in i.e. user_is_logged is undefined for home.component.ts ( where login logic is written ), I ask the user to login and after successful login am updating the value of user_is_logged variable and also updating the localStorage value of the variable and then triggering detect changes by using the ChangeDetectionRef(cdr) and then routing to user profile
this.user_is_logged = "1";
localStorage.setItem('logged', '1');
this.cdr.detectChanges();
this.router.navigate(['u/'+user_id']); //user_id is from login response from server
The problem is when I reach the user profile after successful login the value of {{ user_is_logged }} never updates even when am using the variable itself or using the value from localStorage or even calling for detection.
Is it possible to do it this way or do I have to add header-block to every page separately? Please ask for more information if I missed something.
EDIT ============>
So after going through Subject, BehaviourSubject, AsyncSubject, ReplaySubject, Observables and what not I just couldn't get this to work. This is the last code I have written :
home.page.component.ts (where login happens and has to emit the event)
import { HomeService } from '../services/home.service';
// No observable or subject imported here.
login() {
// Sending status 1 to HomeService
this.HomeService.changeStatus("1");
}
home.service.ts (which is imported by both component)
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
// I imported Subject, BehaviourSubject, Observables but cant get it to work
export class HomeService {
// This looked more reliable than Subject so used this; init with value "0"
public subjectStream = new BehaviorSubject<string>('0');
constructor(
){
this.subjectStream.subscribe(value => {
// Successfully logs value "1" sent by changeStatus below
console.log(value);
});
}
changeStatus(value: any){
// Gives value "1" when called by home.page.component.ts
console.log(value);
// Looks correct because it successfully sent value to construct
this.subjectStream.next(value);
}
}
header.block.component.ts
import { HomeService } from '../services/home.service';
// No observable or subject imported here also.
constructor(
){
this.HomeService.subjectStream.subscribe(value => {
// Logs value "0" at beginning but never logs value "1"
console.log(value);
});
}
My Log
// logged by constructor when imported by header.block.component
home.service.ts:31 0
// logged by constructor of header.block.component itself
header.block.component.ts:25 0
// logged by constructor when imported by home.page.component (I think)
home.service.ts:31 0
// ===================
// Login called here
// ===================
// logged by changeStatus after login after called by home.component
home.service.ts:36 1
// logged by constructor after getting event from changeStatus
home.service.ts:31 1
What am I missing in header.block.component.ts? As the value is successfully updated within the home.service.ts but never goes to header.
If you provide HomeService
in homepage and header, you get 2 instances of HomeService
. If you want to share a service, then provide it only once on the parent component. If you want to share a single instance with your whole application, provide it only at @NgModule()
of AppModule
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With