Greentube / localize-router

An implementation of routes localisation for Angular
MIT License
193 stars 93 forks source link

Localize router unable to pass data params on an empty path #152

Open lee-wilkins opened 5 years ago

lee-wilkins commented 5 years ago
**I'm submitting a **
[x] bug report => Search github for a similar issue or PR before submitting
[ ] feature request => Please check if similar feature request does not exist
[ ] support request => Suggested place for help and support is [stackoverflow](https://stackoverflow.com/), search for similar question before posting

Description

In order to switch the navbar color on the homepage I have the following situation in my app-routing.module

const routes: Routes = [
  { path: '', loadChildren: 'app/external/external.module#ExternalModule' },
  { path: 'dashboard', loadChildren: 'app/internal/internal.module#InternalModule' },
  { path: 'authenticate', loadChildren: 'app/auth/auth.module#AuthModule' },
];

in external-routing.module:

const routes: Routes = [{
  path: '',
  component: ExternalComponent,
  children: [
    {
      path: '',
      component: HomepageComponent,
      data: { navbarInverse: true },
    },
    ....
}];

Note the deep empty route.

The page loads the first time fine. However if i switch the language on the homepage i get:

core.js:14597 ERROR TypeError: Cannot read property 'path' of undefined

Inspecting the error shows that in the code a data attribute causes the path to be split by "/", which obviously cannot happen in my case as i have an empty path.

localize-router.service.js:117

            else if (snapshot.routeConfig.data) {
                var subPathSegments = snapshot.routeConfig.data.localizeRouter.path.split('/');
                return subPathSegments
                    .map(function (s, i) { return s.indexOf(':') === 0 ?
                    snapshot.url[i].path :
                    _this.parser.translateRoute(s); })
                    .join('/');
            }

I can fix this by re-routing my homepage to /home as such, but this is not ideal:

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '', loadChildren: 'app/external/external.module#ExternalModule' },
  { path: 'dashboard', loadChildren: 'app/internal/internal.module#InternalModule' },
  { path: 'authenticate', loadChildren: 'app/auth/auth.module#AuthModule' },
];
const routes: Routes = [{
  path: '',
  component: ExternalComponent,
  children: [
    {
      path: 'home',
      component: HomepageComponent,
      data: { navbarInverse: true },
    },
    ....
}];

🌍 Your Environment

**Angular Version: 7.1.1


Angular CLI: 7.1.0
Node: 10.8.0
OS: darwin x64
Angular: 7.1.1
... animations, common, compiler, compiler-cli, core, forms
... http, platform-browser, platform-browser-dynamic, router
... service-worker

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.10.2
@angular-devkit/build-angular     0.10.2
@angular-devkit/build-optimizer   0.10.2
@angular-devkit/build-webpack     0.10.2
@angular-devkit/core              7.1.0
@angular-devkit/schematics        7.1.0
@angular/cdk                      7.1.0
@angular/cli                      7.1.0
@angular/fire                     5.1.1
@angular/language-service         7.0.0
@angular/pwa                      0.11.0
@ngtools/webpack                  7.0.2
@schematics/angular               7.1.0
@schematics/update                0.11.0
rxjs                              6.3.0
typescript                        3.1.3
webpack                           4.19.1

Localize Router Version:


    "localize-router": "^2.0.0-RC.2",
    "localize-router-http-loader": "^1.0.2",
Kateriine commented 5 years ago

Same issue here, I temporarily removed the data.

I just tested with data: { skipRouteLocalization: true }, it causes the same issue.

cariboufute commented 5 years ago

I have the same problem and I have been able to fix it by making a quick fix in parseSegmentValue function in the localize-router.service.ts file.

The culprit is the condition else if (snapshot.routeConfig.data). When the route has a data key, snapshot.routeConfig.data returns both the object with the localizeRouter and the data key content.

To avoid this, I add a condition to check if there is a localizeRouter in the data (else if (snapshot.routeConfig.data && snapshot.routeConfig.data.localizeRouter)

Here is the whole method. Please check my fork for the fix : https://github.com/cariboufute/localize-router

// src/localize-router.service.ts
// ...

/**
   * Extracts new segment value based on routeConfig and url
   * @param snapshot
   * @returns {string}
   */
  private parseSegmentValue(snapshot: ActivatedRouteSnapshot): string {
    if (snapshot.routeConfig) {
      if (snapshot.routeConfig.path === '**') {
        return this.parser.translateRoute(snapshot.url
          .filter((segment: UrlSegment) => segment.path)
          .map((segment: UrlSegment) => segment.path)
          .join('/'));
      } else if (snapshot.routeConfig.data && snapshot.routeConfig.data.localizeRouter) {
        const subPathSegments = snapshot.routeConfig.data.localizeRouter.path.split('/');
        return subPathSegments
          .map((s: string, i: number) => s.indexOf(':') === 0 ?
            snapshot.url[i].path :
            this.parser.translateRoute(s))
          .join('/');
      }
    }
    return '';
  }