Route navigation in Angular4 not reacting - html

I have made an Angular4 component and the page that it generates has a button to navigate to another page. I don't get any errors and the pageUrl changes but the content of the page stays the same.
Here is my code:
app.component.ts
import { Component } from '#angular/core';
import { Router } from "#angular/router";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private router: Router){}
username = "";
password = "";
log = function () {
if (this.username != "" && this.password != "") {
console.log(this.username + " " + this.password);
this.router.navigate(['/dashboard']);
}
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard/dashboard.component';
#NgModule({
declarations: [
AppComponent,
DashboardComponent,
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{
path: 'dashboard',
component: DashboardComponent
}
]
)
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {
}
app.component.html
<div class="outer-container">
<div class="inner-container">
<div class="centered-content">
<div class="center"><img src="../favicon.png"></div>
<label class="addText"> Username: </label><input [(ngModel)]
="username" class="addText"><br>
<label class="addText"> Password: </label><input [(ngModel)]
="password" type="password" class="addText"><br>
<div class="center"><button (click) ="log()">Log in</button></div>
</div>
</div>
</div>

To achieve what you want, have the app.component only to include the router-outlet:
#Component({
selector: 'app-root',
template: `
<!-- Views go here-->
<router-outlet></router-outlet>
`,
})
export class AppComponent { }
And then have a separate component for each view you want. So in your case you'd want to create a LoginComponent, which would then route to the DashboardComponent from there.
PS Of course this is expandable and you could add a header component tag in the AppComponent html, or whatever else and so on and so on. But just to showcase this simple use case.

you need to specify where to display the DashboardComponent
add this tag to tell angular the location where to display the component results from router
<router-outlet></router-outlet>

Related

Angular: Form-Submit should forward to new component

I have two components. In the app.component.ts users have a form in which they can enter data. If you then click the Submit button, you should be forwarded to an app.show.component.ts, but I don't know how to make this link.
<button mat-raised-button fxFlex type="submit" color="accent">Submit configuration</button>
Can someone please fix it?
if by forward you mean that you should load a new page, then you can use navigate method from Router module when the data is submitted:
HTML
<button mat-raised-button (click)="onSubmit()" fxFlex type="submit" color="accent">Submit configuration</button>
app.component.ts
import { Component } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(private router: Router) { }
onSubmit() {
this.router.navigate('/show')
}
}
app-routing.module
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { ShowComponent } from './show/show.component';
const routes: Routes = [
{
path: '',
component: AppComponent
},
{
path: '/show',
component: ShowComponent
}
];
#NgModule({
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Might seem complicated, at first, but there is a lot of articles and documentation about Angular Routing.
Angular Router

How to send FormData with another FormControl using Reactive form in angular 6?

I make a form with some fields like email user name and avatar using reactive form of angular 6. I know i need form data to upload image, but i dont know how to using it with reactive form in angular 6. Anyone can help ?
Try this:
<form [formGroup]="yourForm" (ngSubmit)="onSubmit()">
<input type="text" formControlName="email"> <br>
<input (change)="uploadDocument($event)" type="file" accept=".png, .pdf, .jpg, .jpeg"> <br>
<input (change)="onSubmit()" type="submit" value="Send file">
</form>
in your app.component.html, then:
import { Component } from '#angular/core';
import { FormBuilder, FormGroup } from '#angular/forms';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
yourForm: FormGroup;
constructor(private fb: FormBuilder, private http: HttpClient) {
this.yourForm = this.fb.group({
email: [''],
file: ['']
});
}
uploadDocument(event: any) {
if (event.target.files && event.target.files[0]) {
const reader = new FileReader();
reader.onload = () => {
this.yourForm.get('file').setValue(event.target.files[0]);
};
reader.readAsDataURL(event.target.files[0]);
}
}
onSubmit(): void {
const uploadData = new FormData();
uploadData.append('email', this.yourForm.get('email').value);
uploadData.append('file', this.yourForm.get('file').value);
this.http.post('your-route', uploadData);
}
}
in your app.component.ts, and:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { HttpClientModule } from '#angular/common/http';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule
],
declarations: [AppComponent, HelloComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
in your app.module.ts file.
Also, don't forget to configure the route in line this.http.post('your-route', uploadData);.

Nav toolbar and side nav not coming in other components

I have searched for this question a lot but still unable to find the solution.
In my app, the after successful logging in the page shows the side nav and toolbar. When an item(component) is clicked in side nav, the respective component is displayed but toolbar does not and also side nav.
Here are the files I have written,
app.component.html
<div *ngIf="user_id !== undefined">
<app-applayoutmodel></app-applayoutmodel>
</div>
<div class="container">
<router-outlet></router-outlet>
</div>
app.component.ts,
import { Component, Input, OnInit } from '#angular/core';
import { Router, NavigationExtras, ActivatedRoute , Params} from '#angular/router';
import * as globals from '../app/pages/models/myGlobals';
import { LoginService } from '../serviceProviders/loginservice';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
title = 'app';
user_id: string = undefined;
constructor(
private route: ActivatedRoute,
private router: Router,
private loginservice: LoginService ) {}
ngOnInit() {
if ( this.router.url.length === 1) {
this.user_id = undefined;
} else {
console.log('Url ' + this.router.url);
const urlParam = this.router.parseUrl(this.router.url).queryParams['property_id'];
this.loginservice.user_id = urlParam;
this.user_id = this.loginservice.user_id;
}
// subscribe to router event
}
}
app-routing.module.ts,
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
import { LoginComponent } from './pages/login/login.component';
import { AppComponent } from './app.component';
import { DashboardComponent } from '../app/pages/dashboard/dashboard.component';
const routes: Routes = [
{path: 'login', component: LoginComponent},
{path: '', redirectTo: '/login', pathMatch: 'full'},
{path: 'applayout', component: AppComponent},
{path: 'dashboard', component: DashboardComponent}
];
#NgModule({
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: []
})
export class AppRoutingModule { }
applayoutmodel.component.html,
<div class="page">
<mat-toolbar color="primary" class="toolbar">
<div>
<button class="menuButton" mat-icon-button (click)="sidenav.toggle()"><mat-icon>menu</mat-icon></button>
<span class="companyName">YAANA</span>
</div>
</mat-toolbar>
<mat-sidenav-container class="sideContainer" fullscreen autosize style="top: 80px !important;">
<mat-sidenav #sidenav mode="push" opened="false" class="sideNav">
<mat-nav-list>
<nav class="menuItems">
<a routerLink="/dashboard">Dashboard</a>
</nav>
<nav class="menuItems">
<a routerLink="/login">Login</a>
</nav>
</mat-nav-list>
</mat-sidenav>
</mat-sidenav-container>
</div>
applayoutmodel.component.ts,
import { Component, OnInit } from '#angular/core';
import { Router, NavigationExtras } from '#angular/router';
#Component({
selector: 'app-applayoutmodel',
templateUrl: './applayoutmodel.component.html',
styleUrls: ['./applayoutmodel.component.scss']
})
export class ApplayoutmodelComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit() {
}
}
Here are the output screens,
After successful loggin in, the firt page is,
When I click dashboard which is listed inside side nav, the output screen is,
But what I need even though after clicking dashboard item inside side nav, the dashboard component view should be displayed along with toolbar and side nav button just like in output screen one.
Please help me to solve this issue, I am not getting any ideas.
Please try this:
- in your app.component.html remove ngIf:
<div>
<app-applayoutmodel></app-applayoutmodel>
</div>
<div class="container">
<router-outlet></router-outlet>
</div>
- in your app-routing.module.ts you need to put your dashboard component as child component of AppComponent like this:
const routes: Routes = [
{path: 'login', component: LoginComponent},
{path: '', redirectTo: '/login', pathMatch: 'full'},
{ path: 'applayout',
component: AppComponent,
children: [
{path: 'dashboard', component: DashboardComponent }
]
}
];
#NgModule({
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: []
})
export class AppRoutingModule { }
This is because you want your applayoutmodel component always to be availible even if you click on 'dashboard'. This is where your router-outlet jumps-in:
he renders your Dashboard component in place of tag, and preserves applayoutmodel component rendered and intact. Please try this and let me know...

how to navigate(redirect) to another page in Angular?

I'm trying to redirect to another page(Page-II) when a button clicked but unfortunately that another page component loads on the same page(Page-I). Here what I tried so far :
app.component.html
<button (click)="register()"
mat-raised-button class="searchButton" type="button">Register</button>
<button (click)="profile()"
mat-raised-button class="searchButton" type="button">Profile</button>
<router-outlet></router-outlet>
app-routing.module.ts
const routes: Routes = [{
path : 'register',
component : RegisterComponent
},
{
path : 'profile',
component : ProfileComponent
}];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.component.ts
import { Component , OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
constructor(private router: Router ) {}
register = function () {
location.pathname = ('/register');
};
profile = function(){
this.router.navigateByUrl('/profile');
};
ngOnInit() {
}
}
Note: I know that profile loads on same page but trying to redirect register.html when register button clicks on another page.
Can you try this:
register() {
this.router.navigate(['/register']);
}

Can't I use a component defined in a file other than app.component.ts in HTML directly?

I am facing difficulty in using a component defined in a file named navigation.component.ts directly on HTML Page.
The same component works fine if I use it under template of a component defined on app.component.ts.
Contents of app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { NavigationComponent} from './shared/navigation.component';
#NgModule({
imports: [BrowserModule],
declarations: [AppComponent, NavigationComponent],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Contents of navigation.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'navigation',
templateUrl: '/views/shared/navigation.html'
})
export class NavigationComponent {
userName: string = 'Anonymous';
}
Contents of app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'main-app',
template: '<navigation></navigation><h1>{{pageTitle}}</h1>'
})
export class AppComponent {
pageTitle: string = 'Portal 2.0';
}
Contents of index.html
<body>
<main-app></main-app>
</body>
The above works and renders menus on top but when I try to use <navigation> directly (given below) it doesn't render it, doesn't show any errors either.
<body>
<navigation></navigation>
</body>
Am I doing something wrong?
And the bigger question is how I go debugging issues like this?
Yes you can use web components. Add all the components that you want to load to entrycomponents.
Using createCustomElement you can create elements and use their selector anywhere.
import { BrowserModule } from '#angular/platform-browser';
import { NgModule, Injector } from '#angular/core';
import { createCustomElement } from '#angular/elements';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
entryComponents: [AppComponent]
})
export class AppModule {
constructor(private injector: Injector) {
console.log('Elements is loaded: Activation');
this.registerComponent('metro-activation-loader', AppComponent);
}
public ngDoBootstrap(): void {
console.log('Elements is loaded: Activation ngDoBootstrap');
}
// tslint:disable-next-line:no-any
private registerComponent(name: string, component: any): void {
const injector = this.injector;
const customElement = createCustomElement(component, { injector });
customElements.define(name, customElement);
}
}