3

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?

2
  • I think ngrx does that automatically and wait for observable to resolved before render it Commented Sep 20, 2017 at 15:29
  • I found solution here stackoverflow.com/a/45104515/3931068 Observable needs to be finished Commented Sep 21, 2017 at 6:28

2 Answers 2

2

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); }); } } } 
Sign up to request clarification or add additional context in comments.

Comments

0

I tried to implement your solution in a resolver instead of a guard, it populates well my ngrx store, but the navigation is not done, I am stuck on the page where I call the route with resolver from. Also in the store we can see the data and router-store/requested and router-store/navigation but not router-store/navigated, neither router-store/cancel like when a guard blocks the navigation. Do you know what I miss and why nothing happends on the navigation side? I used the resolver in my route this way:

 { path: "params/users", canActivate: [IsAdminGuard], component: UsersComponent, resolve: { usersLoaded: UsersResolver } } 

And here is the resolver, almost like your guard:

@Injectable() export class UsersResolver implements Resolve<boolean> { constructor(private store: Store<appState>) {} resolve( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> { // API calls with ngrx effect this.store.dispatch(usersActions.GET_USERS_TRY()); // Select users in store, switchMap(true) if array not empty return this.store.pipe( select(UsersSelectors.allUsers), filter((allUsers: users[]) => allUsers.length > 0), switchMap((allUsers: users[]) => return of(true)) ); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.