Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Angular resolver inject router

I defined a resolver in my Angular (v13) app to do some shenanigans with a wordpress backend. When the user accesses an URL I want the resolver to check post type and ID from wordpress and route accordingly (post list, single post, page, …).

To do that I have injected Angular’s Router in my WordPressResolver class, but when I call router.navigate(...) I get the following error :

ERROR TypeError: Cannot read properties of undefined (reading ‘navigate’)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

It seems like the router is not injected, but I cannot figure out why. I added the @Injectable decorator on my resolver and provided it in the routing module.
Here are my routing module and resolver code.

app.module.routing.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { NotFoundComponent } from './modules/not-found/not-found.component';
import { WordPressResolver } from './wordpress-resolver';

const routes: Routes = [
  {
    path: 'posts',
    loadChildren: () =>
      import('./modules/posts/posts.module').then((m) => m.PostsModule),
  },
  {
    path: 'single/:id',
    loadChildren: () =>
      import('./modules/post/post.module').then((m) => m.PostModule),
  },
  {
    path: 'page/:id',
    loadChildren: () =>
      import('./modules/page/page.module').then((m) => m.PageModule),
  },
  {
    path: '**',
    component: NotFoundComponent,
    resolve: {
      error: WordPressResolver,
    },
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [WordpressResolver],
})
export class AppRoutingModule {}

wordpress-resolver.ts

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  Resolve,
  Router,
  RouterStateSnapshot,
} from '@angular/router';
import { environment } from 'src/environments/environment';
import { UrlData } from './shared/model/url-data.interface';
import { UrlType } from './shared/model/url-type.enum';

@Injectable({ providedIn: 'root' })
export class WordPressResolver implements Resolve<HttpErrorResponse | null> {
  constructor(private http: HttpClient, private router: Router) {}

  private error: HttpErrorResponse | null = null;

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): HttpErrorResponse | null {
    this.http
      .get<UrlData>(environment.domain + state.url)
      .subscribe(this.resolveSuccess, this.resolveError);

    return this.error;
  }

  private resolveSuccess(urlData: UrlData): void {
    switch (urlData.type) {
      case UrlType.POSTS:
        this.router.navigate(['/posts'], { skipLocationChange: false });
        return;
      case UrlType.POST:
        this.router.navigate(['/post', urlData.id], {
          skipLocationChange: false,
        });
        return;
      case UrlType.PAGE:
        this.router.navigate(['/page', urlData.id], {
          skipLocationChange: false,
        });
        return;
      default:
        return;
    }
  }
  private resolveError(error: HttpErrorResponse): void {
    this.error = error;

    this.router.navigate(['/error'], {
      skipLocationChange: true,
    });
  }
}

(I know ‘/error’ is not mapped yet, this is a work in progress)

>Solution :

You have to define your callback function as arrow function so that you can access global scope

resolveSuccess= (urlData: UrlData): void => { }

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading