Angular2: How to contact parent component with child?

I am loading the div part between the tag. Its like below.

Here is my index.html

<html> <script> System.import('app').catch(function(err){ console.error(err); }); </script> </head> <!-- 3. Display the application --> <body> <my-app>Loading...</my-app> </body> </html> 

app.module.ts

 @NgModule({ imports: [ BrowserModule, FormsModule, AppRoutingModule ], declarations: [ AppComponent, LoginComponent, HomeComponent, NewsfeedComponent, TopBarComponent, SideMenuComponent ], providers : [ AuthGaurd ], bootstrap: [ AppComponent ] }) export class AppComponent {} 

home.component.ts

 @Component({ selector: 'home', moduleId: module.id, templateUrl: 'home.component.html', providers : [ LoginService ] }) export class HomeComponent implements OnInit{ isLoggedin : boolean; constructor (private loginService : LoginService) { } ngOnInit(): void { this.loginService.getLogged().subscribe((isLoggedIn: boolean) => { this.isLoggedin = isLoggedIn; }); } } home.component.html <side-menu *ngIf='isLoggedin'></side-menu> <top-bar *ngIf='isLoggedin'></top-bar> <router-outlet></router-outlet> 

auth.gaurd.ts

 @Injectable() export class AuthGaurd implements CanActivate{ constructor(private router : Router) { } canActivate(){ if (localStorage.getItem('isLogin')){ return true; } this.router.navigate(['/login']) return false; } } 

login.service.ts

 @Injectable() export class LoginService { private subject: Subject<boolean> = new Subject<boolean>(); constructor(private router : Router) { } login(){ this.setLogged(true); localStorage.setItem("isLogin","true"); this.router.navigate(['/news-feed']); } logout(){ this.setLogged(false); localStorage.removeItem("isLogin"); this.router.navigate(['/login']); } getLogged(): Observable<boolean> { return this.subject.asObservable(); } setLogged(val : boolean): void { this.subject.next(val); } } 

login.component.ts

 @Component({ selector: 'login', moduleId: module.id, templateUrl: 'login.component.html' }) export class LoginComponent { constructor (private loginService : LoginService) { } login(){ this.loginService.login() } } 

login.component.html

 <input type="number" #mobileNumber /> <input type="password" #password /> <input type="button" (click)="login()"> 

newsfeed.component.ts

 @Component({ selector: 'newsfeed', moduleId: module.id, templateUrl: 'newsfeed.component.html', }) export class NewsfeedComponent { } 

newsfeed.component.html

some html text .... !!!!

application-routing.module.ts

 @NgModule({ imports: [ RouterModule.forRoot([ { path : 'login', component : LoginComponent }, { path : 'news-feed', component : NewsfeedComponent, canActivate : [AuthGaurd] }, { path : '', redirectTo : '/news-feed', pathMatch : 'full' } { path: '**', component: LoginComponent } ]) ], exports: [ RouterModule ] }) export class AppRoutingModule {} 

Actually, it works great when I go with clicks. how its launch is perfect than when you press the login button, it sends news and shows the expected result. but when I navigate from the browser url without loading the sidebar and the top bar component from home.html

+5
source share
2 answers

I'm not sure if this fixes everything, but I think you want to read the value from localstorage first to get the newly saved status, and if you use BehaviorSubject , listeners also get the latest status if this.subject.emit() was called until the subscriber subscribed.

 @Injectable() export class LoginService { //private subject: Subject<boolean> = new Subject<boolean>(false); private subject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(); // <<< changed constructor(private router : Router) { this.sublect.next(logalStorage.getItem('isLogin')); // <<< added } login(){ this.setLogged(true); localStorage.setItem("isLogin","true"); this.router.navigate(['/news-feed']); } logout(){ this.setLogged(false); localStorage.removeItem("isLogin"); this.router.navigate(['/login']); } getLogged(): Observable<boolean> { return this.subject.asObservable(); } setLogged(val : boolean): void { this.subject.next(val); } } 
+1
source

I ran into this problem. This is how I solve this situation;

  • Create a shared service with observable fields as described in angular white papers.
  • In the navigation bar component, subscribe to the value from the shared service to display the navigation bar
  • On the login and logout pages, enter the update value. Since you have already signed the value, the subscriber processes this situation on his own
  • Create an authentication service. Add a method similar to this to ask your server the request is authenticated;
 //method parameters depend on what you want isAuthorized(url: string, errorCallback: (any) => void) { let body = JSON.stringify(url) return this.http.post('account/isauthorized', body) .map((response: Response) => { //update value to display navigation bar if user is authenticated yourSharedService.observableField.next(true); return true; }) .catch((response: Response) => { errorCallback(response.status); return Observable.of(false); }); } 
  • Create authentication protection and call the isAuthorized method in canActivate or canLoad or CanActivateChild .

  • Handle unauthorized requests in your callback. You can redirect the user to error pages or delete the navigation bar and everything you want.

Hope this helps!

+3
source

Source: https://habr.com/ru/post/1259535/


All Articles