简体   繁体   中英

How to move subscription from component to resolve

In my Angular app in my component i'm making two subscription to two Observables with switchMap that gets data from two API, when the component is opened i have to show a skeleton or a loader and i would prevent it, so i've just read about the Resolve which as i understand preload the data and then activate the route.

So i was wondering on how could i move the following subscription from ngOnInit to a Resolver

Here is how my ngOnInit looks like now

  ngOnInit(): void {
    this.menuService
      .menu(this.idNegozio, this.piva, 'IT')
      .pipe(
        switchMap((menu) =>
          forkJoin([
            of(menu),
            this.pluService.plu(this.idNegozio, this.piva, 'IT'),
          ])
        )
      )
      .subscribe(([menu, plus]) => {
        this.menu = menu;
        this.plus = plus;
        this.filterPlu(menu[0].id);
        if (this.filteredPlu.length) {
          this.ready = true;
        }
      });
  }

And that same component is used in three routes:

  {
    path: 'asporto',
    component: ProductsComponent,
    canActivate: [ItemsGuardService]
  },
  {
    path: 'takeaway',
    component: ProductsComponent,
  },
  {
    path: 'ecom',
    component: ProductsComponent,
  },

Create a resolver

 @Injectable() export class MenuResolver implements Resolve<Menu>{ constructor(private menuService: MenuService, private pluService: PluService) {} resolve(route: ActivatedRouteSnapshot): Observable<Menu> { const piva = route.parent.params.piva; const negozio = route.parent.params.negozio; return this.menuService .menu(negozio, piva, 'IT') .pipe( switchMap((menu) => forkJoin([ of(menu), this.pluService.plu(negozio, piva, 'IT'), ]) ), map(([menu, plus]) => ({ menu, plus })) ); } }

Use it in your routes definition and provide it in your parent module

 const routes: Routes = [ { path: '', resolve: { menu: MenuResolver }, component: Component, } ]; @NgModule({ imports: [ RouterModule.forChild(routes), ], providers: [ MenuResolver, ] }) export class MyModule { }

Then get it in your component via ActivatedRoute

 export class MyComponent { menu: Menu; plus: MenuDetails; constructor(private route: ActivatedRoute){} ngOnInit() { const menuData = this.route.snapshot.data.menu; this.menu = menuData.menu; this.plus = menuData.plus; } }

You will have to add the resolver to all of the concerned routes, and use it the same way in the components

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM