I have a problem with my app.component.html, i'm using this block:
<router-outlet *ngIf="!accessGranted"></router-outlet>
<div *ngIf="accessGranted" class="wrapper">
<app-header></app-header>
<app-left-menu></app-left-menu>
<router-outlet></router-outlet>
<app-footer></app-footer>
<app-right-menu></app-right-menu>
</div>
When the accessGranted
is false i load the login theme, when accessGranted
its true i load everything from the dashboard. Ok this is perfect, works i expected. But the problem is... how to update the variable accessGranted
from a service? currently i have this in app.component.ts:
app.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ThemeService } from './services/theme.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
title = 'SmartliveWeb';
accessGranted: boolean;
constructor (private _themeService: ThemeService) {
this.accessGranted = _themeService.accessGranted;
}
}
theme.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ThemeService {
accessGranted = false;
constructor() {
}
}
When user login in the app i want to change accessGranted
to true to change the theme, but always stay in false. Any way to apply the changes in app.component when the accessGranted
in service changes?
To update the value in the component you need to create an Observable of that variable, so when changes the variable fire the value and the component can listen it. For example:
private static accessGranted = new Subject();
accessGranted$ = ThemeService.accessGranted.asObservable();
onLogin(){
if(loginSuccess){
ThemeService.accessGranted.next(true);
}else{
ThemeService.accessGranted.next(false);
}
}
And in the app.component you can subscribe as follow:
ngOnInit(){
this._themeService.accessGranted$
.subscribe((res) => this.accessGranted = res)
}
But I think this isn't the right way to do this. You can use as children route and use the route guards provided from angular like canActivate. Have more information here: CanActivate Doc
You could write a method to service and make accessGranted
an Observable
or even better: a BehaviorSubject
.
In service:
export class ThemeService {
private accessGrantedSubject$: BehaviorSubject<boolean> = new BehaviorSubject(false);
accessGranted = () => this.accessGrantedSubject$.asObservable();
constructor() {
}
setAccessGranted = (isGranted: boolean): void => {
this.accessGrantedSubject$.next(isGranted);
}
}
In component:
export class AppComponent implements OnInit, OnDestroy {
title = 'SmartliveWeb';
accessGranted: Observable<boolean>;
constructor (private _themeService: ThemeService) {
this.accessGranted = this._themeService.accessGranted();
}
}
And in template, you can use async
pipe:
<div *ngIf="accessGranted | async" class="wrapper">
...
</div>
If you want to change the accessGranted
property, you could call the setAccessGranted()
method of the service.
Hope that helps.
your assignment in constructor is wrong
constructor (private _themeService: ThemeService) {
this.accessGranted = _themeService.accessGranted;
}
constructor (private themeService: ThemeService) {
this.themeService = themeService;
}
login()
{
this.themeService.login((res) => {
this.themeService = res;
});
}
in your theme service implement login and return true
on success
this can be achieved by using shared service. This is how the code will look like:
Create a new file Service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class SharedService {
// Subject (emitter) for User Name Change
AccessGrantChange: Subject<boolean> = new Subject<boolean>();
// SetUserChange() - This method sets the local variable and emits the change
SetAccessGrant(param: boolean) {
this.AccessGrantChange.next(param);
}
}
In your login component once you get the result from service, ie in subscribe method write the following code:
this._sharedService.SetAccessGrant(newCityName);
Make sure that in the constructor you have injected the service class. And in app.component.ts file in ngOnInit subscribe to the event and change the value:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ThemeService } from './services/theme.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
title = 'SmartliveWeb';
accessGranted: boolean;
constructor (private _themeService: ThemeService) {
_themeService.accessGranted = this.accessGranted;
}
ngOnInit(){
this._sharedService.AccessGrantChange
.subscribe((value) => {
this..accessGranted=value;
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.