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 {
}
Related
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.
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 am trying to learn angular 2 routing and I am stuck here I can't get the template of child component to display. I have the following two pages
page1.ts
import {Component} from 'angular2/core';
#Component({
selector: "page1",
template: `page 1 goes here.`
})
export class Page1Cmp{}
page2.ts
import {Component} from 'angular2/core';
import {RouterLink,RouteConfig} from 'angular2/router';
import {ChildCmp} from './child';
#Component({
selector: "page2",
template: `Hello its page 2
<router-outlet></router-outlet>`
})
#RouteConfig([
{path: "/", component: ChildCmp, name: "Child", useAsDefault: true}
])
export class Page2Cmp{}
Here is the child component that page2.ts is trying to route
child.ts
import {Component} from 'angular2/core';
#Component({
selector: "child",
template: `child content goes here.`
})
export class ChildCmp{}
This child component is not being displayed on page2
Here is the root component
app.ts
import {Component} from "angular2/core";
import {bootstrap} from "angular2/platform/browser";
import {ROUTER_DIRECTIVES, RouteConfig, ROUTER_PROVIDERS} from "angular2/router";
import {Page1Cmp} from './page1';
import {Page2Cmp} from './page2';
#Component({
selector: "app",
template: `<a [routerLink]="['Page1']">Page1</a> | <a [routerLink]="['Page2']">Page2</a>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
#RouteConfig([
{path: "/page1", name: "Page1", component: Page1Cmp, useAsDefault: true},
{path: "/page2/...", name: "Page2", component: Page2Cmp}
])
class MyApp{}
bootstrap(MyApp, [
ROUTER_PROVIDERS
]);
When I route to page2 I don't see the template of child.ts component. I re-produced the problem on plunker here
plunker
import {RouterLink,RouteConfig,ROUTER_DIRECTIVES} from 'angular2/router';
#Component({
selector: "page2",
directives: [ROUTER_DIRECTIVES],
//add this and it will start working as expected.
template: `<br>Hello its page 2<br>
<router-outlet></router-outlet>`
})
I have an app component where the routes are defined and the <router-outlet></router-outlet> is set. I also have a menu component where I would like to set the [routerLink] using the app routes. How do I link bought of them together (Share routes).
App Component:
import {Component, View} from 'angular2/core';
import {ROUTER_PROVIDERS,RouteConfig} from 'angular2/router';
import {bootstrap} from 'angular2/platform/browser';
import {HomeComponent} from './../../components/home/home';
#Component({
selector: 'app',
moduleId: module.id,
providers: [
ROUTER_PROVIDERS
]
})
#View({
templateUrl: 'app.html',
styleUrls: ['app.css']
})
#RouteConfig([
{ path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true }
])
class AppComponent {
}
bootstrap(AppComponent);
Menu Component:
import {Component, View} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
#Component({
selector: 'left-side-column',
moduleId: module.id,
})
#View({
templateUrl: 'left-side-column.html',
styleUrls: ['left-side-column.css']
})
class LeftSideColumnComponent {
}
bootstrap(LeftSideColumnComponent);
When you use the bootstrap function twice, you create several independent applications.
If you want that your menu uses routes defined in the AppComponent, you need to use the corresponding component into the app one and bootstrapping it.
Something like:
import { MenuComponent } from '...';
#Component({
(...)
template: `
<left-menu></left-menu>
<router-outlet></router-outlet>
` ,
directives: [ ROUTER_DIRECTIVES, MenuComponent ]
})
export class AppComponent {
}
bootstrap(AppComponent, [ ROUTER_PROVIDERS ]);
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.