Angular reusable resolvers

Hello!

At the moment, I am working at my new project – Page Health .

It is a SaaS platform which provides a page performance monitoring on the long run.

In this application I had a lot of cases, where I had to duplicate the code of my resolvers to…


This content originally appeared on DEV Community and was authored by Igor Filippov

Hello!

At the moment, I am working at my new project - Page Health .

It is a SaaS platform which provides a page performance monitoring on the long run.

In this application I had a lot of cases, where I had to duplicate the code of my resolvers to make very, very similar things.

That's why I took thought about how to implement the DRY coding principle in my app.

First, I take a glance at official angular documentation .

And here I found an interesting way to implement resolvers with in-line functions.

export const myHero: Hero = {
  // ...
}

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'detail/:id',
        component: HeroComponent,
        resolve: {
          hero: 'heroResolver'
        }
      }
    ])
  ],
  providers: [
    {
      provide: 'heroResolver',
      useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => myHero
    }
  ]
})
export class AppModule {}

So, I decided to create a function which will return a reusable provider.

export function createPageResolver(redirectRoute: string): Provider {
  return {
    provide: "pageResolver",
    deps: [NotificationsService, PagesApiService, Router],
    useFactory: (n: NotificationsService, p: PagesApiService, r: Router) => {
      return new PageResolver(n, p, r, redirectRoute);
    }
  }
}

Let's explain it step by step:

provide - it is the name of my provider.

deps - is shorten for the word - dependencies. In my case I need some services to do my stuff and Router from @angular/router to redirect user if condition in resolve function is not match.

useFactory - unlike the example in the official docs, I need it, because in my case I need to return a new instance of resolver, not a simple value.

And actually code of my resolver.

... imports here

export class PageResolver implements Resolve<PageDto> {
  constructor(
    private notificationsService: NotificationsService,
    private pagesApiService: PagesApiService,
    private router: Router,
    @Inject("redirectRoute") private redirectRoute: string,
  ) {}

  resolve(route: ActivatedRouteSnapshot): Observable<PageDto> {
    const param: string = route.params["id"];
    const pageId: number = Number(param);

    if (isNaN(pageId)) {
      this.notificationsService.error("Invalid page id.");
      this.router.navigate([this.redirectRoute]);
      return of(null);
    } else {
      return this.pagesApiService.getUserPage(pageId)
        .pipe(
          catchError((e) => {
            console.error(e);
            this.notificationsService.error("Unable to get this page.");
            this.router.navigate([this.redirectRoute]);
            return of(null);
          }),
        );
    }
  }
}

By the way, the code can be extended with custom error message, depending on situation, but in my case a static message is completely enough.

Also, please note, that I did not add an @Injecable() decorator for my resolver class, because, injection happens in useFactory method.

If you do not fully understand how to use it, here is an example.

... imports here

const routes: Routes = [
  {
    path: "",
    component: PageSpeedComponent,
    children: [
      ... some other routes
      {
        path: ":id",
        component: PageSpeedMetricsComponent,
        data: {
          title: "Chrome User Experience Report"
        },
        resolve: {
          page: "pageResolver",
        },
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  providers: [
    createPageResolver("/user-experience"),
  ],
})
export class PageSpeedRoutingModule {}

Hope, this small technick will be useful for somebody :)


This content originally appeared on DEV Community and was authored by Igor Filippov


Print Share Comment Cite Upload Translate Updates
APA

Igor Filippov | Sciencx (2021-09-06T10:16:33+00:00) Angular reusable resolvers. Retrieved from https://www.scien.cx/2021/09/06/angular-reusable-resolvers/

MLA
" » Angular reusable resolvers." Igor Filippov | Sciencx - Monday September 6, 2021, https://www.scien.cx/2021/09/06/angular-reusable-resolvers/
HARVARD
Igor Filippov | Sciencx Monday September 6, 2021 » Angular reusable resolvers., viewed ,<https://www.scien.cx/2021/09/06/angular-reusable-resolvers/>
VANCOUVER
Igor Filippov | Sciencx - » Angular reusable resolvers. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/06/angular-reusable-resolvers/
CHICAGO
" » Angular reusable resolvers." Igor Filippov | Sciencx - Accessed . https://www.scien.cx/2021/09/06/angular-reusable-resolvers/
IEEE
" » Angular reusable resolvers." Igor Filippov | Sciencx [Online]. Available: https://www.scien.cx/2021/09/06/angular-reusable-resolvers/. [Accessed: ]
rf:citation
» Angular reusable resolvers | Igor Filippov | Sciencx | https://www.scien.cx/2021/09/06/angular-reusable-resolvers/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.