0

Angular is not resolving my route parameter and I don't understand why.... GAH.

This is my routes file for the lazy module;

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AssignedOrdersResolver } from 'src/app/common/services/partner/resolvers/assigned-orders.resolver';
import { PartnerResolver } from 'src/app/common/services/partner/resolvers/partner.resolver';
import { AssignedOrdersComponent } from './assigned-orders/assigned-orders.component';
import { PartnerComponent } from './partner.component';
import { SettingsComponent } from './settings/settings.component';
import { ShowComponent } from './show/show.component';

const routes: Routes = [
  {
    path: ':partnerId',
    component: PartnerComponent,
    resolve: {
      partner: PartnerResolver
    },
    children: [
      {
        path: '',
        component: ShowComponent
      },
      {
        path: 'assigned-orders',
        component: AssignedOrdersComponent,
        resolve: {
          orders: AssignedOrdersResolver
        }
      },
      {
        path: 'settings',
        component: SettingsComponent
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class PartnerRoutingModule { }

This is an example of how I'm constructing the links

          <li class="nav-item">
            <a
              class="nav-link"
              [routerLink]="['/partners', partner.id, 'assigned-orders']"
              routerLinkActive
            >
              Assigned Orders
            </a>
          </li>

This is my resolver:

import { Injectable } from '@angular/core';
import {
  Resolve,
  RouterStateSnapshot,
  ActivatedRouteSnapshot
} from '@angular/router';
import { Observable, of } from 'rxjs';
import { PartnerService } from '../partner.service';

@Injectable({
  providedIn: 'root'
})
export class AssignedOrdersResolver implements Resolve<boolean> {

  constructor(private readonly parter: PartnerService) { }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    const id = route.params.partnerId;
    return this.parter.getAssignedOrders(id);
  }
}

Communication with the server fails because the partnerId is not present in the params of the ActivatedRoute as per:

GET http://localhost:3000/v1/fulfillment-partners/undefined/assigned-orders 500 (Internal Server Error)

This is the ActivatedRoute that appears in the resolver:

component: class AssignedOrdersComponent
data: {}
fragment: undefined
outlet: "primary"
// PARAMS ARE EMPTY
params: {} // <<<---- PARAMS EMPTY ???
queryParams: {}
routeConfig: {path: "assigned-orders", resolve: {…}, component: ƒ}
url: [UrlSegment]
_lastPathIndex: 2
_resolve: {orders: ƒ}
// ID PRESENT IN URL STRING
_routerState: RouterStateSnapshot {_root: TreeNode, url: "/partners/1/assigned-orders"} // <<<---- ID SHOWING HERE ???
_urlSegment: UrlSegmentGroup {segments: Array(3), children: {…}, parent: UrlSegmentGroup}
children: (...)
firstChild: (...)
paramMap: (...)
parent: (...)
pathFromRoot: (...)
queryParamMap: (...)
root: (...)
__proto__: Object

Plz explain.

Ed Stephenson
  • 704
  • 1
  • 8
  • 31

1 Answers1

3

You need to access to a parent route parameter, so you have to do route.parent.paramMap.get('partnerId') in your resolver to get it.

JB Belin
  • 46
  • 3
  • Great - thank you. Have to say, I don't prefer this way; makes the resolver less flexible, but at least it works. Thanks again. – Ed Stephenson Mar 24 '21 at 10:30
  • @Ed Stephenson, if you want more flexibility, you can move your resolver at the same level as the PartnerResolver. Resolvers are resolved in parallel, so it won't be less efficient. In your child component, you will be able to access to the orders by `this.activatedRoute.parent.data`. For my part I prefer working with Rxjs, so in your case I would use a BehaviorSubject or a ReplaySubject to access data anywhere in any component. – JB Belin Mar 24 '21 at 13:06