Angular2 Routing - Child template not dispalying - javascript

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>`
})

Related

Angular 2 routerLink not working inside router-outlet

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.

Angular 2 Routing in more then one component

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 ]);

How to render partial inside template

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

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 {
}

Angular 2 - Is it possible to store my routes in another file and import them into the app.ts file (because over time the routes will build up)?

Angular 2 - Is it possible to store my routes in another file and import them into the app.ts file (because over time the routes will build up)
Here is an example of my current app.ts that works. I basically want to move the route config routes to another file to make it cleaner:
import {Todo} from './components/todo/todo';
import {About} from './components/about/about';
import {AuthService} from './authService';
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';
#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){
//Subscribe - watches routes pop state events.
router.subscribe((val) => {
_authService.isUserLoggedIn().then((success) => {
router.parent.navigate(['/About']);
});
})
}
}
bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'}), AuthService]);
i personally have created an route.interface.ts and a route.ts files.
Routes file
import {Route} from './route.interface'
import {AuthComponent} from './auth/auth.component'
export const Routes: Route[] = [
{
path: '/auth',
name: 'Authenticate',
component: AuthComponent
},
];
Route Interface
export interface Route {
path: string,
name: string,
component: any,
}
Usage in main component.
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router'
import {Routes} from './routes'
#Component({
selector: 'app',
templateUrl: './angular2/app/layout.component.html',
directives: [
ROUTER_DIRECTIVES
],
providers: [
HTTP_PROVIDERS,
ROUTER_PROVIDERS
],
})
#RouteConfig(Routes)
Hope that helps. you can even create a route service and inject it you main component. Enjoy coding!
You can add your RouteConfig per component
Lets say you have home and about as in your example, then you would define the routing from that specific component in the component itself.
So in your about component you can add
// './components/about/about'
#RouteConfig([
{ path: '/about', component: About, as: 'About' }
])
And in your home component you can do the same
// './components/home/home'
#RouteConfig([
{ path: '/home', component: Todo, as: 'Home' }
])

Categories