3
votes

right now I have a resolver calling standard service and returning an Observable:

return this.someService.getData()
      .map(data=> data.json())

I want to replace it with ngrx effects and store. When resolver is run I want to dispatch requestAction intercepted by effect, which makes http request. Once data is returned I dispatch dataReceivedAction with data as payload.

Basically i want to dispatch an action in resolver and wait till new data is in part of store. I try to do it this way:

return Observable.combineLatest(
      Observable.of(
        this.store.dispatch(new requestAction())
      ),
      this.store.select(store => store.dataIWaitFor),
      (dispatchedAction, dataArrived) => dataArrived
    )
      .skip(1)

it's not working, I mean the resolver doesn't render the component but when at the end of each of these returned Observables I add

.do(data => console.log(data))

the same data is logged. What I do wrong?

1
I think ngrx does that automatically and wait for observable to resolved before render itAniruddha Das
I found solution here stackoverflow.com/a/45104515/3931068 Observable needs to be finishedJarosław Rewers

1 Answers

2
votes

You can do something like this

@Injectable()
export class SomeGuard implements CanActivate {
constructor(private store: Store<AppState>) {}

waitForDataToLoad(): Observable<Something> {
    return this.store.select(state => state.something)
        .filter(something => something && !something.empty);
}

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
    this.store.dispatch({type: LOAD_something});

    return this.waitForDataToLoad()
        .switchMap(() => {
            return Observable.of(true);
        });
    }
}
}