Store: Actions Subscribe

Created on 22 Mar 2018  ·  10Comments  ·  Source: ngxs/store

Versions

* ngxs: 2.0.0-rc.18
* @angular/core: 5.2.9

Repro steps

  • Step 1: Defining Async Actions
@Action(SearchPeoples)
  serarchPeoples({ getState, setState }: StateContext<ParkStateModel>) {
    const state = getState();
    this.http.get<Search>('https://randomuser.me/api/?results=5').subscribe(value => {
      console.log('updating the state...');
      setState({
        ...state,
        search: value.results
      });
      console.log('status updated.');
    });
  }
  • Step 2: Creating function to dispatch action and subscribe
search() {
    this.store.dispatch(new SearchPeoples()).subscribe(value => {
      console.log('The action is completed.');
    });
  }
  • Step 3: Call function search

Observed behavior

In the browser console displays:
captura

Desired behavior

I hoped log first : updating the state...
then : status updated.
and finally: The action is completed.

I thought to subscribe only receive a result when the action will update the status.
It is in this way that should work or not?

Most helpful comment

This may be something we need to do in the lib itself

On Thu, Mar 22, 2018, 4:19 PM Angel Núñez Podio notifications@github.com
wrote:

It works well!! with shareReplay()


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/ngxs/core/issues/138#issuecomment-375443692, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AGQnJZUNJ5iKN7E6o0fblADDi7IsnL5yks5thAdRgaJpZM4S3ot0
.

All 10 comments

The problem here is that the dispatch observable finishes before the observable inside your action since it isn't waiting for the observable inside the action.

What happens if you return the Observable from the action and instead of subscribing to it use a rxjs operator, like tap() to do the work inside the observable?

@yarrgh sorry, I did not understand, You can give me an example?

In your action:

@Action(SearchPeoples)
  serarchPeoples({ getState, setState }: StateContext<ParkStateModel>) {
    const state = getState();
    return this.http.get<Search>('https://randomuser.me/api/?results=5').pipe(
      tap(value => {
        console.log('updating the state...');
        setState({
          ...state,
          search: value.results
        });
        console.log('status updated.');
      })
    );
  }

I've changed the action to return the Observable and do the logic inside the tap() rxjs operator.

@yarrgh I get it!. But that gives another problem:

captura

it appears that executes the action several times

I think subscribing to the Observable returned from dispatch() is causing the action to be dispatched again. Looks like a bug to me. The observable should be something like a BehavoirSubject where it doesn't trigger on multiple subscriptions but only the first subscription (subscribed internally in ngxs?).

Not sure how the action is dispatched the 3rd time though.

Well, it looks like a bug.

@amcdnl any suggestions?

This can be worked around by using the shareReplay() rxjs operator.

Example:

@Action(SearchPeoples)
  serarchPeoples({ getState, setState }: StateContext<ParkStateModel>) {
    const state = getState();
    return this.http.get<Search>('https://randomuser.me/api/?results=5').pipe(
      tap(value => {
        console.log('updating the state...');
        setState({
          ...state,
          search: value.results
        });
        console.log('status updated.');
      }),
      shareReplay()
    );
  }

It works well!! with shareReplay()

This may be something we need to do in the lib itself

On Thu, Mar 22, 2018, 4:19 PM Angel Núñez Podio notifications@github.com
wrote:

It works well!! with shareReplay()


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/ngxs/core/issues/138#issuecomment-375443692, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AGQnJZUNJ5iKN7E6o0fblADDi7IsnL5yks5thAdRgaJpZM4S3ot0
.

I tried the version ngxs: 2.0.0-rc.21 and keep making multiple requests

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CheckMater picture CheckMater  ·  5Comments

ToxicToast picture ToxicToast  ·  6Comments

mfp22 picture mfp22  ·  3Comments

paulstelzer picture paulstelzer  ·  5Comments

garthmason picture garthmason  ·  5Comments