RouteParams in Angular 2 rc1 - javascript

I've been trying out Angular 2 since beta, and now with rc.0+ some things have changed.
One of those are RouteParams which cannot be imported from #angular/router. And when I try with #angular/router-deprecated I get an error message:
ORIGINAL EXCEPTION: No provider for RouteParams!
app.component:
#Routes([
{ path: '/', component: StartComponent },
{path: '/:projId/:userName', component: ProjectListComponent},
{ path: '*', component: StartComponent },
])
project-list.component:
import {Component, OnInit} from '#angular/core';
import {RouteParams} from '#angular/router-deprecated';
#Component({
...
})
export class ProjectListComponent implements OnInit {
userName:string;
projId:string;
constructor(private params:RouteParams) {
this.userName = params.get('userName');
this.projId = params.get('projId');
}
}
Where can I import the RouteParams from now, or is it something else I'm doing wrong?
Thanks!

One way is
routerOnActivate(curr: RouteSegment) {
this.userName = curr.getParam('userName');
this.projId = curr.getParam('projId');
}

You have to use RouteSegment instead of using RouteParams in angular2 RC. like this :-
import { Component } from '#angular/core';
import { Routes, RouteSegment, ROUTER_DIRECTIVES } from '#angular/router';
#Component({
selector: 'about-item',
template: `<h3>About Item Id: {{id}}</h3>`
})
class AboutItemComponent {
id: any;
constructor(routeSegment: RouteSegment) {
this.id = routeSegment.getParam('id');
}
}
#Component({
selector: 'app-about',
template: `
<h2>About</h2>
<a [routerLink]="['/about/item', 1]">Item 1</a>
<a [routerLink]="['/about/item', 2]">Item 2</a>
<div class="inner-outlet">
<router-outlet></router-outlet>
</div>
`,
directives: [ROUTER_DIRECTIVES]
})
#Routes([
{ path: '/item/:id', component: AboutItemComponent }
])
export class AboutComponent { }

Related

Angular Route with encoded query params not being resolved

In my Angular 10 application I have a route like this
http://localhost:4200/employee/enrollments?number=189930097&city=Chicago
Sometimes the URL is being encoded as
http://localhost:4200/employee/enrollments%3Fnumber%3D189930097%26city=Chicago
and router fails to find a match. Is there a way to fix this decoding issue and make it resolve always?
Update:
I added my footer component in which I am using routerLink that updates the current URL
EmployeeRoutingModule:
export const enrollmentManagementRoutes: Routes = [
{
path: 'enrollments',
component: EnrollmentSearchComponent,
canActivate: [EmployeeAuthGuardService],
}
];
#NgModule(
{
imports: [
RouterModule.forChild(enrollmentManagementRoutes)
],
exports: [
RouterModule
]
})
export class EmployeeRoutingModule
{
}
FooterComponent
import {Component, OnInit} from '#angular/core';
import {NavigationEnd, Router} from '#angular/router';
import {environment} from '../../../environments/environment';
#Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements OnInit
{
appVersion: any;
currentUrl='/';
constructor(private router: Router)
{
}
ngOnInit()
{
this.appVersion = environment.VERSION;
//Update Need Assistance link URL, this prevents default URL being '/'
this.router.events.subscribe(data=>
{
if(data instanceof NavigationEnd)
{
this.currentUrl=data.url+'';
}
});
}
navigateByUrl()
{
this.router.navigateByUrl(this.currentUrl);
}
}
Footer Component HTML:
<a class=" col-sm-12 col-xs-12 col-md-auto request-help-link" id="request-help-link" rel="noopener noreferrer"
[routerLink]="currentUrl" style="font-size: 20px" >
Need Assistance? Click here
</a>
Would it not make more sense to use a route parameter than a query string?
export const enrollmentManagementRoutes: Routes = [
{
path: 'enrollments:number',
component: EnrollmentSearchComponent,
canActivate: [EmployeeAuthGuardService],
}
];
and then route to http://localhost:4200/employee/enrollments/189930097
and in your component you can use the ActivatedRoute service to get the param.
https://angular.io/api/router/ActivatedRoute
Have you tried to use something like custom serializer?
serializer.ts
export class CustomUrlSerializer implements UrlSerializer {
parse(url: any): UrlTree {
const dus = new DefaultUrlSerializer();
return dus.parse(url);
}
serialize(tree: UrlTree): any {
const dus = new DefaultUrlSerializer();
const path = dus.serialize(tree);
// use your regex to replace as per your requirement.
path.replace(/%3F/g, '?');
path.replace(/%3D/g, '=');
return path;
}
}
and then in App module
...
providers: [
{provide: UrlSerializer, useClass: CustomUrlSerializer}
],
...

Toggle Component depending on route Angular 4

Hey there Im trying to toggle a component on and off, but I cant seem to get it to work...
app.component.ts
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { NgIf } from '#angular/common';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'app';
router: string;
constructor(private _router: Router)
{
this.router = _router.url;
}
}
app.component.html
<app-header></app-header>
<app-header-home *ngIf="router !== ''"></app-header-home>
<router-outlet></router-outlet>
<app-footer></app-footer>
route configuration
export const ROUTES: Routes = [
{ path: '', component: HomeComponent, pathMatch="full" },
{ path: 'who-we-are', component: WhoWeAreComponent},
{ path: 'our-technology', component: OurTechnologyComponent},
{ path: 'our-work', component: OurWorkComponent },
{ path: 'get-in-touch', component: GetInTouchComponent }
];
index.html
<base href="/">
so basically If I start at home I want the app-header-home component shown but then as soon as I navigate to a new section I want app-header-home to hide but then If I go back to home I want it to show up again
Thanks
You want to subscribe to route changes, and the change a boolean flag depending on route in your typescript:
import { Component, OnInit } from '#angular/core';
import { Router, Event, NavigationStart } from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
routeHidden = true;
constructor(
private router: Router) { }
ngOnInit() {
this.router.events.subscribe( (e) => {
if (e instanceof NavigationStart) {
if (e.url === "/") {
this.routeHidden = false;
} else {
this.routeHidden = true;
}
}
})
}
}
and in your html template:
<app-header-home *ngIf="routeHidden"></app-header-home>
Try using the ActivatedRoute service
constructor(private route: ActivatedRoute){
this.router= route.snapshot.url.join('');
}

#Input or service not working in Component

I am trying to make import a service inside a component but when I call the Input coming from this service, in my template, it does not render anything.
Here is my entity:
export interface PageState {
step: string;
}
export class SimplePageState implements PageState {
step: string;
}
Here is my service:
import { Injectable } from '#angular/core';
import { PageState } from './state.entity';
#Injectable()
export class PageStateService {
getPageState(): Promise<PageState[]> {
const step = [{ 'step': '1' }];
return Promise.resolve(step);
// return this.http.get('/api/status');
}
}
I am importing and instantiating these in my main component:
import { Component, OnInit } from '#angular/core';
import { Module } from '../modules/core/module.entity';
import { ModuleService } from '../modules/core/module.service';
import { PageState } from './state.entity';
import { PageStateService } from './state.service';
#Component({
selector: 'df-esign',
templateUrl: './esign-page.html',
styleUrls: ['./esign-page.scss'],
providers: [ ModuleService, PageStateService ]
})
export class EsignComponent implements OnInit {
modules: Module[];
pageState: PageState[];
constructor(private moduleService: ModuleService, private pageStateService: PageStateService) { }
getModules() {
this.moduleService.getModules().then(modules => this.modules = modules);
}
getPageState() {
this.pageStateService.getPageState().then(pageState => this.pageState = pageState);
}
ngOnInit() {
this.getModules();
this.getPageState();
}
}
And finally, I am using SimplePageState inside of a particular component, this way:
import { Component, Input } from '#angular/core';
import { SimpleModule } from '../core/module.entity';
import { SimplePageState } from '../../core/state.entity';
#Component({
selector: 'df-module-page',
templateUrl: './module-page.html',
styleUrls: ['./module-page.scss'],
})
export class ModulePageComponent {
#Input() module: SimpleModule;
#Input() pageState: SimplePageState;
}
But trying to do {{pageState}} in my template gives me a blank result with no error.. Anybody can help? I've spent hours looking on the internet and trying to make it work.
Edit:
I am trying to use it inside a bread-crumbs component.
Here is the beginning of my module-view.html, which contains df-module-page as well as df-module-bread-crumbs:
<ng-container [ngSwitch]="module.type">
<template [ngSwitchCase]="'PageModule'"><df-module-page [module]="module" [pageState]="pageState"></df-module-page></template>
<template [ngSwitchCase]="'TextModule'"><df-module-text [module]="module"></df-module-text></template>
<template [ngSwitchCase]="'BreadCrumbModule'"><df-module-bread-crumb [module]="module" [pageState]="pageState" class="{{module.class}}"></df-module-bread-crumb></template>
I am calling SimplePageState in the bread-crumb-component too:
import { Component, Input, HostBinding } from '#angular/core';
import { SimpleModule } from '../core/module.entity';
import { SimplePageState } from '../../core/state.entity';
#Component({
selector: 'df-module-bread-crumb',
templateUrl: './module-bread-crumbs.html',
styleUrls: ['./module-bread-crumbs.scss']
})
export class ModuleBreadCrumbsComponent {
#Input() module: SimpleModule;
#Input() pageState: SimplePageState;
}
And I am trying to do an ngIf inside of module-breads-crumbs.html with a pageState condition which does not have any effect:
<div class="dfbreadcrumbs">
<ol *ngIf="module">
<li *ngFor="let crumb of module.slots.crumbs; let i = index" class="step_{{i + 1}}">{{crumb.text}}</li>
</ol>
</div>
<div *ngIf="pageState">ohohoh</div>
To pass data to an input you would need something like
<df-module-page [pageState]="pageState">
in the template of EsignComponent

Routing not working in Angular2

My Routing isn't working in Angular2, to demonstrate the point, I have put the same component as the destination for both the root of my site and /login. The component works at http://localhost:3000, but at http://localhost:3000/login, I just get a notice "Cannot GET /login".
app.component.ts:
import { Component } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import {TodoService} from './todo/services/todo.service';
import { TodoCmp } from './todo/components/todo.component';
import { LoginComponent } from './user/components/login.component';
import { UserService } from './user/services/user.service';
#Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<router-outlet></router-outlet>
`,
styleUrls: ['client/dev/todo/styles/todo.css'],
directives: [ROUTER_DIRECTIVES],
providers: [
ROUTER_PROVIDERS,
TodoService
]
})
#RouteConfig([
{
path: '/',
name: 'TodoCmp',
component: TodoCmp,
useAsDefault: true
},
{
path: '/login',
name: 'TodoCmp',
component: TodoCmp
}
])
export class AppComponent {
title = 'ng2do';
}
Here is a link to my index file.
What have I done wrong?
Two routes in one #RouteConfig(...) can't have the same name:
#RouteConfig([
{
path: '/',
name: 'TodoCmp',
component: TodoCmp,
useAsDefault: true
},
{
path: '/login',
name: 'TodoCmp', <!-- <<<== should be 'Login' instead of 'TodoCmp'
component: TodoCmp
}
])
You should move ROUTER_PROVIDERS to bootstrap() (like HTTP_PROVIDERS)

Angular 2 - I'm trying to navigate to another route using router.parent.navigate

Angular 2 - I'm trying to navigate to another route using router.parent.navigate.
However, the error I get is this: "EXCEPTION: TypeError: Cannot read property 'navigate' of null" in my console log.
This is my current code:
import {Component, View, bootstrap, bind, provide} from 'angular2/angular2';
import {Router, ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router';
import {Location, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {Todo} from './components/todo/todo';
import {About} from './components/about/about';
import {AuthService} from './authService';
#Component({
selector: 'app'
})
#View({
template: `
<div class="container">
<nav>
<ul>
<li><a [router-link]="['/Home']">Todo</a></li>
<li><a [router-link]="['/About']">About</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
</div>
`,
directives: [RouterOutlet, RouterLink]
})
#RouteConfig([
{ path: '/', redirectTo: '/home' },
{ path: '/home', component: Todo, as: 'Home' },
{ path: '/about', component: About, as: 'About' }
])
export class AppComponent {
constructor(_router: Router, _authService: AuthService, _location: Location){
_router.subscribe((val) => {
_authService.isUserLoggedIn().then((success) => {
//This part below is not working:
_router.parent.navigate(['/About']);
});
})
}
}
bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'}), AuthService]);
I think you should use the ngOnInit method.
export class AppComponent implements OnInit {
constructor(router: Router, authService: AuthService, location: Location){
}
ngOnInit(){
this.router.subscribe((val) => {
this.authService.isUserLoggedIn().then((success) => {
//This part below is not working:
this.router.parent.navigate(['/About']);
});
})
}
}

Categories