3

I have a base route with three sibling routes. The parent route routes to my task-list.component.ts which contains a navbar and router outlet.

I would like to have a route param on the base route where I can add an optional token

so when I navigate to http://localhost:4200 token should be undefined.

when I navigate to http://localhost:4200/123 token should be 123 in the activated route params

I have the below route config but i'm encountering confusing/strange behaviour.

When I navigate to http://localhost:4200 I get to my base taskList.component as expected.

When I try navigate to http://localhost:4200/123 I get a 404 not found? The expected bahaviour is that this should have navigated to taskList.component and added 123 to the activated route params...

even more strange when I click the deleted link in my navbar it navigates to the parent component app.component again only then I get "deleted" as the value in the activated route params...

Even more strange: when I navigate to http://localhost:4200 using my browser it doesn't set deleted as token instead I get a 404 not found again...

Any idea how I can achieve the above/what my issue might be?

my route module code:

    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    
    import { AppComponent } from './app.component';
    import { TaskListComponent } from './task/task-list/task-list.component';
    import { CompletedTasksComponent } from './task/completed-tasks/completed-tasks.component';
    import { DeletedTasksComponent } from './task/deleted-tasks/deleted-tasks.component';
    
    
const routes: Routes = [  
  { path: '', component: TaskListComponent, pathMatch: 'full' },
  { path: 'completed', component: CompletedTasksComponent },
  { path: 'deleted', component: DeletedTasksComponent },
  { path: ':token', component: TaskListComponent },  
  { path: ':token/completed', component: CompletedTasksComponent },
  { path: ':token/deleted', component: DeletedTasksComponent }
];
    
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }

app.component.html:

<nav mat-tab-nav-bar>
    <a mat-tab-link
    *ngFor="let link of links"
    [routerLink]="navigate(link)"
    (click)="activeLink = link"
    [active]="activeLink == link">{{link}}</a>
    

    </nav>


<router-outlet></router-outlet>

app.component.ts navigate method

navigate(link) {
    switch(link) {
      case 'Task List':
        return `${this.token}`;
      case 'Completed Tasks':
        return `${this.token}/completed`;
      case 'Deleted Tasks':
        return `${this.token}/deleted`;
    }
  }
yaya
  • 7,675
  • 1
  • 39
  • 38
user2094257
  • 1,645
  • 4
  • 26
  • 53
  • so in token you mean backend token from login/other form of authentication? – Jack M Aug 21 '20 at 08:16
  • @Jack M for now I just want to add any test value as a parameter to the root e.g. localhost:4200/testToken should have the value testToken in route params. – user2094257 Aug 21 '20 at 09:05
  • I am not sure if I understand your problem: valid routes here are localhost:4200/token and token/completed and token/deleted those should display the content of their component. Is that not happening? – Jack M Aug 21 '20 at 11:08
  • @Jack M No I want to add a route param to those routes and resolve the param in te route e.g. if my token is 123 and route definition is :token/ when I make a request to localhost:4200/123 the token value in route.params must be 123 – user2094257 Aug 21 '20 at 11:24
  • well if 1234blabla is an id from somewhere then you need to replace :token by /:id I don't know if that will work though i have only done it when we have 'token/:/id' – Jack M Aug 21 '20 at 12:43

1 Answers1

4

Old answer: You have some issues in your routes. you can fix it like :

    RouterModule.forRoot([
      { path: "", component: TaskListComponent, pathMatch: "full" },
      { path: "deleted", component: DeletedTasksComponent },
      { path: ":id", component: TaskListComponent },
      { path: ":id/completed", component: CompletedTasksComponent },
      { path: ":id/deleted", component: DeletedTasksComponent }
    ])

Run It On Stackblitz

Update : based on your edit and comments, now in app navigation works but you get 404 when you refresh the page (even in development environment). so try this: https://stackoverflow.com/a/35285068/4718434 . (Also on production, you should configure your server to return angular html file on every path.)

yaya
  • 7,675
  • 1
  • 39
  • 38
  • I still want to be able to resolve the id when I hit localhost:4200/123 (id in route params should then be 123) however i'm getting a 404 not found... Any idea how I can achieve this? – user2094257 Aug 22 '20 at 15:12
  • I updated the question with a more detailed description of the issue... – user2094257 Aug 22 '20 at 17:59
  • @user2094257 there is a bug in your question. `AppComponent` is the main component of the app, and it contains the `router-outlet`. so you shouldn't use in in your routes. you should create a separate component like `app-main-component` to use in routes as main route, so it'll be placed inside `router-outlet`. and for simplicity, please remove `children` for now and use simple routes, since you don't seem to be familiar enough with angular routing system, and it just makes things complicated. updated the answer. – yaya Aug 22 '20 at 21:09
  • the only issue is if the home component is inside the how could I re-use my navbar/keep track of which route is active in the navbar without copying the navbar to the deleted and completed components? – user2094257 Aug 23 '20 at 06:53
  • @user2094257 `how could I re-use my navbar?` -> way1. simply create a component called navbar and use it in multiple pages. way2. write navbar outside `router-outlet` in app component. ||| `how can i keep track of which route is active` -> with using ``, it adds a css for actived links. – yaya Aug 23 '20 at 07:35
  • thanks navbar works in appComponent outside router. Please see bounty description and updated question. i'm still getting a 404 when I navigate to localhost:4200/123 with your suggested route config changes... – user2094257 Aug 23 '20 at 08:15
  • @user2094257 for `deleted` route issue, that's because when you say: `:id`, it catches `deleted` as id. to prevent this, you should know that order in routes is important. you should put `deleted` route on top of `:id` route. for `:id` issue, it works for me. edited the answer and added a stack-blitz demo. – yaya Aug 23 '20 at 08:34
  • @user2094257 also added the active class in stackblitz demo. – yaya Aug 23 '20 at 09:22
  • that helps however: when I navigate to localhost:4200/123 or localhost:4200/123/deleted I still get a 404 not found... I updated my routes in question. Any idea what the issue might be? feel like it's something very obvious i'm missing... – user2094257 Aug 23 '20 at 09:28
  • @user2094257 obviously the problem is not because of routes setup, since in here: https://stackblitz.com/edit/angular-router-basic-example-nrwurm?file=app%2Fapp.routing.module.ts it has exact same setup and it works. you get `404 not found` ? so it's not the problem with routing. since you didn't setup any 404 in angular. so maybe angular is not firing. aren't you using `ng serve`? if not, you should setup your server to render `index.html` of angular on every route, or redirect to index : https://stackoverflow.com/questions/50907736/refreshing-the-page-results-in-404-error-angular-6 – yaya Aug 23 '20 at 09:42
  • I haven't deployed this anywhere, encountering this when I serve with ng-cli so it feels like it must be related to the routing config? – user2094257 Aug 23 '20 at 10:48
  • @user2094257 do you use `ng build` or `ng serve` ? do you encounter it only when you directly go to `/deleted` route, or you encounter it also when you use in app navigation (add a link to `deleted` on navbar, and check it.) – yaya Aug 23 '20 at 10:51
  • I use ng serve. in-app navigation works for :token/completed and :token/deleted however when I navigate to :token the token doesn't get added to the URL in the browser. Also I can't directly reach any of those routes except htps://localhost:4200 without getting a 404 not found... – user2094257 Aug 23 '20 at 12:03
  • @user2094257 what you mean by: `when I navigate to :token the token doesn't get added to the URL in the browser` ? when you navigate to `/123/` , you can't see the url in broswer? what about getting `token` param, which one doesn't work? does it redirect you to home? and also, you don't mean that your url is exactly like `htps://localhost:4200/:token` , right? it's just a pattern to catch patterns like: `htps://localhost:4200/123`. i ask it bacause maybe your url is exactly has `:token` in it and it's not a pattern. – yaya Aug 23 '20 at 12:08
  • when I navigate to localhost:4200/123/ I get a 404 not found. and No I don't mean the literal localhost:4200/:token:) I added my in-app navigation code to the question if that helps... – user2094257 Aug 23 '20 at 12:24
  • @user2094257 `when I navigate to localhost:4200/123/ I get a 404 not found` -> i know. it's separate issue. but you said: `when I navigate to :token the token doesn't get added to the URL in the browser`. what you mean by this? what exactly will happen when you click the link of `/123/` ? please add a separate manually link (not generated link like what you put in the question) and add `/123/` link to it, and check what exactly will happen? it does nothing? not changing the url , and not changing anything on the page? – yaya Aug 23 '20 at 12:41
  • yes now in-app navigation works perfectly however I still can't navigate to localhost:4200/123 in my browser, when I click on task list in nav the url changes to localhost:4200/123 (123 is just a test token I hardcoded for now) but when I then reload the page I again get a 404 not found. – user2094257 Aug 23 '20 at 13:00
  • @user2094257 1. so if it works when you hardcode it , it means that your link generator is not working well. maybe `this.token` is empty or etc. (so routes is working. try debugging the route generator with some `console.log` and checking the link href rendered value in broswer.). 2. about 404 not found on refresh, something is wrong with your angular config or version or etc. are you using `platformBrowserDynamic` for bootstrap? like this: https://stackblitz.com/edit/angular-router-basic-example-nrwurm?file=main.ts try these solutions: https://stackoverflow.com/a/39103122/4718434 – yaya Aug 23 '20 at 13:30
  • from my main.ts: platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err)); so yes. what do you mean by my link generator is not working properly? And how can I debug this? Also if the token is empty there shouldn't be a problem, I need the ability to use a token or not... – user2094257 Aug 23 '20 at 13:45
  • hash based routing works so i'm just going to use this for now thanks for all your patience/time... – user2094257 Aug 23 '20 at 13:49
  • @user2094257 No problem, Glad it solved it. by `link generator` i meant the piece of code you're creating links : switch(link) {case 'Task List':return `${this.token}`;). when you hardcode a ` – yaya Aug 23 '20 at 13:55