Reputation: 1788
I know this question is related to component interaction, googled for getting to know but I am not getting what I am missing.
I wanna check for a value of property inside app.component.html In my angular app,
I have login component which takes input value from a user such as user_name and password. Once a user gets authenticated router draws the respective layout.
My try,
app.component.html ( Method 1)
<app-applayoutmodel></app-applayoutmodel>
<div class="container">
<router-outlet></router-outlet>
</div>
app-applayoutmodel this component includes the side nav and toolbar layout and router-outlet is responsible for layout with respective to clicked nav item in side nav.
But I wanted to change the html as follows, (Method 2)
<div *ngIf="user_name !== undefined">
<app-applayoutmodel></app-applayoutmodel>
</div>
<div class="container">
<router-outlet></router-outlet>
</div>
Here for user_name I want to get the value from the login Component once user entered in the form and submitting the form.
app.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'app';
@Input() user_name: string;
}
and login.component.ts
import { Component, OnInit, Inject } from '@angular/core';
import { Router } from '@angular/router';
import { User } from '../models/user';
import { LoginService } from '../../../serviceProviders/loginservice';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';
import { AppComponent } from '../../app.component';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
user_name: string;
password: string;
public user: User;
private errorMsg: string;
constructor(private loginService: LoginService,
private router: Router,
public dialog: MatDialog) { }
ngOnInit() {
}
userLogin() {
console.log(this.user_name);
this.loginService.signIn(this.user_name, this.password)
.subscribe(
data => {
this.user = data;
this.router.navigate(['/applayout']); },
err => {
const dialogRef = this.dialog.open(DialogOverview, {
width: '400px'
});
dialogRef.afterClosed().subscribe(result => {
this.router.navigate(['/login']);
// this.animal = result;
});
this.errorMsg = err;
}
);
}
}
}
and login.component.html
<div class="firstDiv"></div>
<div class="secondDiv"></div>
<div class="loginDiv">
<form>
<div class="row center">
<i class="fa fa-user-circle"></i>
</div>
<div class="container">
<input type="text" matInput placeholder="Username" type="text" name="username" [(ngModel)]="user_name">
<input type="password" matInput placeholder="Password" name="password" [(ngModel)]="password">
<br/>
<br/>
<button mat-button (click)="userLogin()">Login</button>
<br/>
<label>
<input type="checkbox" checked="checked" name="remember"> Remember me
</label>
</div>
</form>
</div>
If I choose method 1 when I open login.component, the view is getting only displayed up to the height of toolbar as like below,
By this, I am unable to proceed with login.
I think Solution is using method 2 because initially when the app gets loaded the user_name is undefined in app.component.html and the app-applayoutmodel does not get displayed and can proceed with the login.
Please help me, how to do the above method 2 if it is correct.
and here are the router paths,
const routes: Routes = [
{path: 'login', component: LoginComponent},
{path: '', redirectTo: '/login', pathMatch: 'full'},
{path: 'applayout', component: AppComponent}
];
Upvotes: 0
Views: 2447
Reputation: 2391
EDIT - NEW ONE THAT USES PARAMS
A better solution is not to put the user name as a query param, but put it as a route param.
To achieve so you have to set your app.routes.ts
:
export const mainRoutes: Routes = [
{ path: '', component: LogInComponent },
{ path: '/:userName', component: MainComponentAfterLogged }
];
After the user filled the form to log in you can:
constructor(private _router: Router) {}
... inside method
this._router.navigate(['this.userName]);
And for your main component, the one that has to receive the user name:
constructor(private _route: ActivatedRoute) {}
ngOnInit() {
this._route.params.subscribe(
params => this.userName = params['userName']
);
NOT SO GOOD WITH QUERY PARAMS
A possible solution would be to put the user name in your URL and subscribe to route changes inside your app camponent. I think it's a good way of resolving your problem because app.component will alwasy get updated when you change your route.
You can refer to this stackoverflow answer to route correctly. Would be something like (inside your login component):
import {Router} from '@angular/router';
userName: string;
constructor(private _router: Router) {}
// ... somewhere inside a method
this._router.navigate([ '', { name: userName } ]);
To subscribe to route changes you could, inside your app.component.ts
:
// Imports needed
import {ActivatedRoute} from '@angular/router';
private sub: any;
userName: string = '';
constructor(private _router: ActivatedRoute) {}
ngOnInit() {
// Subscribe to active route changes
this.sub = this.route.params.subscribe(params => {
// Get the content of param 'name' everytime it changes
this.userName = params['name'];
// call a method or so to do something with that information
});
}
Upvotes: 2