8

I am new to Angular 2 and I have a question regarding routing. I have a app.routing file, in which I only want one path.

{path: 'signup', component: SignupComponent}

But if I run this code I get an error:

Error: Uncaught (in promise): Error: Cannot match any routes: ''

So i decided to just use an empty component on the ' ' path, which works exactly like i wanted.

Routing File:

import {Routes, RouterModule} from '@angular/router';
import {SignupComponent} from "./signup/signup.component";
import {EmptyComponent} from "./empty/empty.component";

const appRoutes:Routes = [
    {path: '', component: EmptyComponent},
    {path: 'signup', component: SignupComponent}
];

export const appRoutingProviders = [];

export const routing = RouterModule.forRoot(appRoutes);

The file with the router-outlet:

<header>
    <div class="btn-wrapper">
        <button class="btn-sign-up btn-fancy" routerLink="/signup">Sign Up</button>
        <button class="btn-sign-in btn-ghost btn-fancy">Sign In</button>
    </div>
    <i class="material-icons more">keyboard_arrow_down</i>
    <router-outlet></router-outlet>
    <div class="overlay" *ngIf="overlay" (click)="close()"></div>
    <div class="tinted"></div>
</header>

I just want that the router only routes the SignupComponent on the 'signup' path. Is there another way to do this and eliminate the use of an empty component? I am sorry if this question is poorly written, I am very new to StackOverflow.

3 Answers 3

9

Just make your empty route redirect to the signup route:

const appRoutes:Routes = [
    {path: '', redirectTo: 'signup', pathMatch: 'full'}, 
    {path: 'signup', component: SignupComponent}
];

Or if you want the router outlet to be empty until you navigate to signup, leave the four totally empty :

const appRoutes:Routes = [
    {path: '', children: []}, 
    {path: 'signup', component: SignupComponent}
];
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for your answer! But I don't want anything to be routed on the path ' '. SignupComponent should only show up on 'signup'.
Thanks again, but now I get this error: Invalid configuration of route '': one of the following must be provided (component or redirectTo or children or loadChildren)
Oh really? That worked on a previous beta but perhaps it doesn't work any more, sorry. Which version of angular are you using? 2.0.0 final?
No problem. Yeah, I am using the 2.0.0 version.
the solution is to add empty children like so, children: []
|
1

Option 1:

If you know that there's nothing to be shown in the child router outlet you can actually hide it. Then you won't get the error.

<router-outlet *ngIf="hasNoQuestionSelected$ | async"></router-outlet>

I feel like this is more technically correct than a 'dummy component', however there are absolutely cases where that is fine and legitimate and probably safer. Even while presenting this as a solution that seems to work it's possible that doing this may add difficult to debug race conditions - which will likely depend on how you determine whether or not to show the outlet.

Curious to hear if people think this is a terrible or legitimate solution.

PS. Don't get confused with Angular's EmptyOutletComponent. This is related but not the same thing, and actually adds a new router-outlet for empty routes.

--

Option 2:

You can have a route that only has a path and no children, component or redirect.

You can still query the ActivatedRoute snapshot and traverse down the tree to find the parameters you need - they're still there. But without a <router-outlet> the router won't try to actually do anything itself - that's up to you. Or you can still define a component and then based on a condition (eg. screen width) decide whether to show or hide a router-outlet to consume it.

Why would I want this you might ask? Sometimes with responsive design for different screen sizes I find myself needing completely different behavior. Sometimes this warrants 'delving' into snapshot.children[0].routeData to pull out the URL parameters. I'll then just display the component myself in the main component.

Just adding this as another alternative for certain cases.

{
    path: 'contactus',
    component: ContactUsComponent,

    children: [
        {
            path: 'topics',
            pathMatch: 'full',
            redirectTo: '/support/contactus'
        },
        {
            path: ':category',

            children: 
            [
                {
                    path: ':question'
                    // component: ContactUsFormComponent
                }
            ]
        }
    ]
},

Comments

-1
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { DemoComponent } from './demo.component';

const demoRoutes: Routes = [
    { path: '', component: DemoComponent }
];

export const demoRouting: ModuleWithProviders = RouterModule.forChild( demoRoutes );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.