My routerLink work outside of my the router-outlet in the navigation component but when I have a page that is within the router-outlet that has a routerlink to a different page I get an error.
browser_adapter.ts:82 TypeError: Cannot read property 'startsWith' of undefined
at UrlParser.parseRootSegment (url_tree.ts:301)
at DefaultUrlSerializer.parse (url_tree.ts:196)
at Router.navigateByUrl (router.ts:242)
at RouterLinkWithHref.onClick (router_link.ts:90)
at DebugAppView._View_ProfileFeedComponent0._handle_click_12_0 (ProfileFeedComponent.template.js:381)
at eval (view.ts:406)
at eval (dom_renderer.ts:274)
at eval (dom_events.ts:20)
at ZoneDelegate.invoke (zone.js:323)
at Object.onInvoke (ng_zone_impl.ts:72)
My router is a basic router.
app.routes.ts
import { provideRouter, RouterConfig } from '#angular/router';
import { HomeComponent } from "./home/home.component";
import {ProfileFeedComponent} from "./profileFeed/profileFeed.component";
import {QuestionComponent} from "./questions/question.component";
import {QuestionAskComponent} from "./questionAsk/questionAsk.component";
export const routes: RouterConfig = [
{path: '', component: HomeComponent, pathMatch: 'full'},
{path: 'profile-feed', component: ProfileFeedComponent},
{path: 'question', component: QuestionComponent},
{path: 'question/ask', component: QuestionAskComponent},
];
export const appRouterProviders = [
provideRouter(routes)
];
export const appRouterProviders = [
provideRouter(routes)
];
app.component.html
<navigation></navigation>
<div class="wrapper">
<router-outlet></router-outlet>
</div>
app.component.ts
#Component({
moduleId: module.id,
selector: "my-app",
templateUrl: "app.component.html",
directives: [ ROUTER_DIRECTIVES, CORE_DIRECTIVES, FORM_DIRECTIVES, NavigationComponent],
})
export class AppComponent {
public viewContainerRef : ViewContainerRef;
public constructor(viewContainerRef:ViewContainerRef) {
// You need this small hack in order to catch application root view container ref
this.viewContainerRef = viewContainerRef;
}
}
//ALL IMPORTS ARE PROPERLY INCLUDED IN THIS FILE
The problem is in this component I believe I just want to have the option to go to a different page within this page, seems straightforward not sure why it is not working. The below page would be inserted into the router-outlet from the menubar navigation. The link('/questions/ask') within this file is not available in the menu bar.
profileFeed.component.ts
import {Component} from "#angular/core";
import {ROUTER_DIRECTIVES, RouterLink, Router} from "#angular/router";
import {ProfileInfoComponent} from "../profileInfo/profileInfo.component";
#Component({
moduleId: module.id,
selector: 'profile-feed',
templateUrl: 'profileFeed.component.html',
styleUrls: ['profileFeed.component.css'],
directives: [
ProfileInfoComponent,
RouterLink,
ROUTER_DIRECTIVES
]
})
export class ProfileFeedComponent {
}
profileFeed.component.html
<div class="profile-feed-container container">
<div class="profile-detail-summary container-fluid">
<profile-info></profile-info>
<hr>
<div class="container-fluid">
<div class="container-fluid">
<a class="btn btn-default" routerLink='/question/ask'>Ask a Question</a>
</div>
</div>
</div>
</div>
The workaround I found to work is use a click method on the link and set a method inside the component's ts file to go to the route needed by using the Router class' navigateByUrl() method. Example:
Component.ts file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit() {
}
goToLoginPage() {
this.router.navigateByUrl("");
}
}
Component.html link
<p>Have an account? <a (click)="goToLoginPage()" class="signup">Sign in</a></p>
The page doesn't fully refresh it acts as if it were a regular <router-outlet> link. I also looked at the network tab and didn't see any new items appear.
Related
History( Push State) forward / backward button doesn't work with angular 2 router.I have tested this in Chrome and Firefox both. Forward button works never and Backward button works only for 2 steps than UI doesn't respond according backward button.
I have following code.
app.component.ts
import { Component } from '#angular/core';
import { ROUTER_DIRECTIVES, Routes } from '#angular/router';
import { CrisisListComponent } from './crisis-list.component';
import { HeroListComponent } from './hero-list.component';
import { Login } from './login';
#Component({
selector: 'my-app',
template: `
<h1>Component Router</h1>
<nav>
<a [routerLink]="['/home']">Crisis Center</a>
<a [routerLink]="['/login']">Login</a>
<a [routerLink]="['/heroes']">Heroes</a>
</nav>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
#Routes([
{path: '/home', component: CrisisListComponent},
{path: '/heroes', component: HeroListComponent},
{path : '/login' , component:Login},
{path: '*', component: CrisisListComponent}
])
export class AppComponent { }
login.ts
import { Component } from '#angular/core';
import { ROUTER_DIRECTIVES, Routes } from '#angular/router';
import { LoginMobile } from './login/login_mobile';
import { LoginEmail } from './login/login_email';
#Component({
template: `
<h2>{{val}}</h2>
<p>Login here</p>\n\
<a [routerLink]="['/login/mobile']">Mobile</a>
<a [routerLink]="['/login/email']">Email</a>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
#Routes([
{path : '/mobile' , component:LoginMobile},
{path : '/email' , component:LoginEmail}
])
export class Login {
val = "kwik.Social";
}
login/login_email.ts
import { Component } from '#angular/core';
#Component({
template: `
<p>Login here</p>
<input type="email" placeholder="Email" [(ngModel)]="email" />\n\
<p>Your Email is {{email}} </p>
`
})
export class LoginEmail {
email = "kwik.Social";
}
After waiting for long time, I tried router by NGRX team. It has many other features as well like Guards , Multiple Components , Child Components and Full History Api support. Only one thing I am missing is that History Api itself doesn't provide a way to get values entered by user on text fields and scroll positions , if that were available Ajax Pages may became more fluid and consistent.
Edit
NGRX router is now deprecated, and Angular Router is inspired from NGRX router and works as expected.
Link to full project without modules: https://www.dropbox.com/s/eaesfz4wvixusn5/EbayClone.zip?dl=0
I'm trying to add a webpage that is called "LogInPage" just for testing purposes.
After running npm start, I get this error which basically says that I should add a "LogInPage" file to the nodes_modules folder. After I do that, I get another error that says missing "async". I'm not sure if my routing is correct because I have tried importing the "login component" but it says it's missing from nodes_modules.
Screenshot of error while trying to load webpage:
enter image description here
App.component.ts code
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {LogInComponent} from 'angular2/LogInPage';
#Component({
selector: 'LogInPageSelector',
template: `
<h1>{{title}}</h1>
<nav>
<a [routerLink]="['LogIn']">Log in</a>
</nav>
<router-outlet></router-outlet>
`,
styleUrls: ['app/app.component.css'],
directives: [ROUTER_DIRECTIVES],
})
#RouteConfig([
{path: '/LogIn', name: 'LogIn', component: Component, useAsDefault: true},
])
export class AppComponent {
title = 'Ebay clone';
}
Code for LogInPage.component.ts
import {Component} from 'angular2/core';
import {Router} from 'angular2/router';
#Component({
selector: 'LogInPageSelector',
templateUrl: 'app/loginpage.component.html',
styleUrls: ['app/loginpage.component.css']
})
export class LogInComponent {
constructor(private LogInService: LogInComponent, private _router: Router) { }
}
loginpage.component.html code:
<html>
<h1>Hello</h1>
</html>
I think that you forgot to include the "router.dev.js" file in your main HTML file:
<script src="node_modules/angular2/bundles/router.dev.js"></script>
I have an application in ts which have this template :
<main>
<test></test>
<router-outlet></router-outlet>
</main>
With this RouteConfig
#RouteConfig([
{ path: '/myApp/game', name: 'GamePage', component: GameComponent, useAsDefault: true}
])
Here are the game component :
import {Component} from 'angular2/core';
#Component({
selector: 'test',
template: '<div>{{title}}</div>'
})
export class GameComponent {
title = "myTest";
constructor(){
console.log("I am constructed")
}
ngOnInit(){
console.log("initGameComponent");
}
}
So this component is imported twice (once by the directive 'test', a second time by the router outlet), which is what I want in order to show the problem.
My problem is that the first time (when I don't use the router) everything's works fine, but the second time, the '{{title}}' is not rendered and the console don't log 'initGameComponent' but DO log 'I am constructed'.
The question is why ?! (Sorry if it's something stupid because I'm starting with angular2, but I really can't figure it out)
Working Plunker -with No issue as you have described
boot.ts
import {Component,bind} from 'angular2/core';
import {Router,ROUTER_PROVIDERS,RouteConfig, ROUTER_DIRECTIVES,APP_BASE_HREF,LocationStrategy,RouteParams,ROUTER_BINDINGS} from 'angular2/router';
import {bootstrap} from 'angular2/platform/browser';
import{GameComponent} from 'src/GameComponent';
#Component({
selector: 'my-app',
template: `
<h1>Component Router</h1>
<hr>
<test></test>
<hr>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES,GameComponent]
})
#RouteConfig([
//{path:'/ComponentOne', name: 'ComponentOne', component: ComponentOne, useAsDefault:true},
{ path: '/myApp/game', name: 'GamePage', component: GameComponent, useAsDefault: true}
])
export class AppComponent {
}
bootstrap(AppComponent, [
ROUTER_PROVIDERS,bind(APP_BASE_HREF).toValue(location.pathname)
]);
GameComponent.ts
import {Component,View} from 'angular2/core';
#Component({
selector:'test',
template: `
<div>{{title}}</div>
`
})
export class GameComponent {
title = "myTest";
constructor(){
console.log("I am constructed")
}
ngOnInit(){
console.log("initGameComponent");
}
}
I think you must replace
<main>
<test></test>
<router-outlet></router-outlet>
</main>
to
<main>
<router-outlet></router-outlet>
</main>
Because router creates own tag. And after routing, DOM will looks like
<main>
<router-outlet></router-outlet>
<test _ngcontent-jll-9=""></test>
</main>
I am using angular 2 for a project and i want to render a partial inside a template without creating a component. Is that possible?
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
#Component({
selector: 'ng2-showroom-app',
providers: [],
templateUrl: 'app/views/ng2-showroom-template.html',
directives: [ROUTER_DIRECTIVES],
pipes: []
})
#RouteConfig([
])
export class Ng2Showroom {
}
ng2-showroom-template
<!-- import navigation.html here -->
<p>
Hello World
</p>
<router-outlet></router-outlet>
Well, if your template is part of another component, call it, NavigationComponent which has a selector of 'navigation-component', then you can add that tag to your ng2-showroom-app template and add the navigation component as a directive...
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {NavigationComponent} from 'src/navigationComponent';
#Component({
selector: 'ng2-showroom-app',
providers: [],
templateUrl: 'app/views/ng2-showroom-template.html',
directives: [ROUTER_DIRECTIVES, NavigationComponent],
pipes: []
})
#RouteConfig([
])
export class Ng2Showroom {
}
<navigation-component></navigation-component>
<p>
Hello World
</p>
<router-outlet></router-outlet>
But I'm guessing what you are really going for is the more common scenario of a master page that has HTML that is always there, and then a template that gets swapped out, based on navigation...
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {Page1Component} from 'src/page1component';
import {Page2Component} from 'src/page2component';
#Component({
selector: 'ng2-showroom-app',
providers: [],
templateUrl: 'app/views/ng2-showroom-template.html',
directives: [ROUTER_DIRECTIVES],
pipes: []
})
#RouteConfig([
{ path: '/page1', as: 'Page1', component: Page1Component },
{ path: '/page2', as: 'Page2', component: Page2Component }])
export class Ng2Showroom {
}
<p>HTML always shown above content, regardless of navigation.</p>
<a [routerLink]="['Page1']">Link to Page 1</a>
<a [routerLink]="['Page2']">Link to Page 2</a>
<router-outlet></router-outlet>
<p>HTML always shown below content.</p>
Now when they click on 'Link to Page 1', whatever you've defined in Page1Component will display within the <router-outlet> placeholder.
Angular2 router-link issue when injecting a template component with router links
I have an app.ts file and I want to dependency inject my navigation component into my app.ts file.
I've made a navigation component that has a template and no functionality.
The template injects fine into app.ts. However, when I add the route-links to the template I always get console errors when using router-links only.
Here is my navigation component ts file:
import {Component, View, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2';
#Component({
selector: 'HeaderNavigation'
})
#View({
templateUrl: '/src/app/components/header/header.html'
})
export class HeaderNavigation{
}
Here is my navigation component html file:
<header>
<nav class="navbar navbar-default">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a [router-link]="['./Login']">Log In</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
</header>
This is my app.ts file: This file injects the navigation component above:
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 {Injectable} from 'angular2/angular2';
import {HTTP_PROVIDERS, Http, Headers} from 'angular2/http';
import {Login} from './components/login/login';
import {HeaderNavigation} from './components/header/header';
#Component({
selector: 'app'
})
#View({
template: `
<HeaderNavigation></HeaderNavigation>
<div class="content">
<router-outlet></router-outlet>
</div>
`,
directives: [RouterOutlet, RouterLink]
})
#RouteConfig([
{ path: '/', redirectTo: '/login' },
{ path: '/login', component: Login, as: 'Login' }
])
#Injectable()
export class AppComponent {
constructor(){}
}
bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'}), HTTP_PROVIDERS]);
This is the error message I get from my console:
I solved my own question!
was missing from the navigation html component and then I had the router-link name wrong and changed it to "Login" from "login" to match it in router config in the app.ts file.
I have made these changes in the above code for anyone who needs it.
For those using angular 2 rc4, here is what i'm using:
header.component.ts
import { Component } from '#angular/core';
import { ROUTER_DIRECTIVES } from '#angular/router';
#Component({
moduleId: module.id,
selector: 'ui-header',
templateUrl: 'header.component.html',
styleUrls: ['header.component.css'],
directives: [ROUTER_DIRECTIVES],
})
export class HeaderComponent{
}
To add header in other component: other.component.ts
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { ROUTER_DIRECTIVES } from '#angular/router';
import { HeaderComponent } from'../shared/header/header.component';
#Component({
selector: 'ui-other',
template: `
<ui-header></ui-header>
<div class = "container">
<router-outlet></router-outlet>
</div>
`,
directives: [ROUTER_DIRECTIVES, HeaderComponent]
})
export class OtherComponent {
}