angularrxjsangular-akita

Angular resolvers with Akita state management


Due to lacking docs (guards, resolvers, routing almost not documented) I'm struggling with Akita state management and the use of Angular resolvers which I always used so far with routing (when not using state mgmt).

I'm looking at the following Gist where author does subscribe inside the component and I'm trying to move that to the resolver.

I've tried multiple variations of including the following lines in resolver and doing subscribe but nothing worked:

this.productsService.get().subscribe();

    this.loading$ = this.productsQuery.selectLoading();

    this.products$ = this.search.valueChanges.pipe(
      startWith(''),
      switchMap(value => this.productsQuery.selectAll({
         filterBy: entity => entity.title.toLowerCase().includes(value)
      }))
    );

Solution

  • You can fetch the data in the resolver and update the store.

    @Injectable()
    class ProductsResolver {
      constructor(private productsService) {}
    
      resolve(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): Observable<any> {
        return this.productsService.getProducts().pipe(
          tap(products => {
            this.productsService.set(products);
          })
        )
      }
    }
    
    
    class ProductsService {
      constructor(private store: ProductsStore) {
    
      }
    
      set(products) {
        this.store.set(products);
      }
    }
    

    In your routes:

    const routes: Routes = [
      {
        path: 'path',
        component: ProductsComponent,
        // The value that returns from the resolver resolve() method
        // will be assign to the products property on ActivatedRoute
        resolve: { products: ProductsResolver }
      }
    ];
    

    Then in your component:

    class Component {
      constructor(private route: ActivatedRoute) {}
    
      ngOnInit() {
        this.products = this.route.snapshot.data['products'];
      }
    }