Waiting for ngrx action before loading page with URL parameter

前端 未结 3 1013
无人共我
无人共我 2020-12-18 01:44

I\'m building an ng2 application using ngrx. When the app is launched a web service is called to get initial data, once this data is fetched I create an INIT_DONE a

相关标签:
3条回答
  • 2020-12-18 02:24

    I would make use of the combineLatest operator as it combines the latest values of multiple source streams. In addition I'd double-check that documents is set (here I assumed it's an array) using filter.

    ngOnInit() {
      this.subscription = Observable.combineLatest(
          this.store.select("documents")
              .filter(documents => documents.length > 0),
          this.paramSubscription = this.route.params
              .select<string>('id')
      )
      .map((combinedData: [Object[], string]) => combinedData[1])
      .subscribe(this.store);
    }
    

    Also assign the subscription to a variable so that you can unsubscribe when the component is destroyed. Otherwise your subscription will be around after the component has been destroyed and it's possible that your action still gets emitted:

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
    
    0 讨论(0)
  • 2020-12-18 02:24

    You could select documents from the store and subscribe to it and emit your action from there:

    ngOnInit() {
      this.store.select("documents").subscribe(documents => {
        this.paramSubscription = this.route.params
          .select<string>('id')
          .map((id) => new SelectAction(id))
          .subscribe(this.store);
      });  
    }
    
    0 讨论(0)
  • 2020-12-18 02:26

    You need a resolver. A resolver waits until data is available before completing the navigation action.

    @Injectable()
    export class DocumentsResolver implements Resolve {
    
        constructor(
            private store: Store
        ) {}
    
        resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> {
            // take id from snapshot
            const id = route.params['id'];
            // start with the document list
            return this.store.select('documents')
              // wait until there is data available
              .filter(documents => documents && documents.length > 0)
              // then produce the selected document
              .mergeMapTo(this.store.select('selectedDocument'));
        }
    }
    

    On route configuration:

    export const DocumentsRoutes: RouterConfig = [
        { path: 'documents/:id', component: DocumentsDetailComponent, resolve: { document: DocumentsResolver } }
    ];
    

    More about router resolve here

    0 讨论(0)
提交回复
热议问题