Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Action from an http requetis fired twice #35

Closed
dbertella opened this issue Feb 27, 2017 · 3 comments
Closed

Action from an http requetis fired twice #35

dbertella opened this issue Feb 27, 2017 · 3 comments

Comments

@dbertella
Copy link

I have a component that at componentDidMount will fire an action that makes an http request.
What I want is to set an isFetching flag in the reducer.
Everything works as expected the first time I load the component, but the second the flag isFetching is never set to true.
I played just a little with the middleware during this weekend so I'm not really sure why I have this problem.

This is my main, I just readapted the code from one of the example.

const fetchPostById = (sources) => {
  const post$ = sources.ACTION
    .filter(action => action.type === ActionTypes.POST_REQUESTED)
    .map(action => action.postId);

  const request$ = post$
    .map(postId => ({
      url: `${BASE_URL}posts/${postId}`,
      category: 'post'
    }));

  const response$ = sources.HTTP
    .select('post')
    .flatten();

  const action$ = xs.combine(post$, response$)
    .map(arr => actions.receivePostById(arr[0], arr[1].body));

  return {
    ACTION: action$,
    HTTP: request$
  }
}

And this is the reducer:

const post = (state = initialPost, action) => {
  switch (action.type) {
    case 'POST_REQUESTED':
      return {
        ...state,
        isFetching: true,
      };
    case 'POST_RECEIVED':
      return {
        ...state,
        isFetching: false,
        [action.postId]: action.post,
      };
    default:
      return state;
  }
};

If I log what's going on with my request, I can see that isFetching is false at the beginning, then the action POST_REQUESTED is fired and isFetching is set to true. When POST_RECEIVED is being fired (from the cycle code) isFetching goes back to false. That's the normal case.
On the next time POST_RECEIVED is being fired two times for the same action and isFetching flag is never set to true.

screen shot 2017-02-27 at 18 19 34

You can see an online version here https://dbertella.github.io/food-and-quote/ in case.
Am I missing something?

@lmatteis
Copy link
Member

lmatteis commented Feb 27, 2017

The problem is with the use of combine: https://github.com/staltz/xstream#-combinestream1-stream2

The second time you call the POST_REQUESTED action from react, it's gonna emit POST_RECEIVED even without a response (because combine uses the latest response).

I think you may need sampleCombine instead (https://github.com/staltz/xstream/blob/master/EXTRA_DOCS.md#-samplecombinestreams) But make sure the source stream is the response.

Hope it makes sense. Let me know if you can figure it out.

@dbertella
Copy link
Author

dbertella commented Feb 27, 2017

Thank you very much! I'll look into it and let you know!
Edit
I couldn't find the right way to make sampleCombine working instead, but I found out that in my case I don't need the combine at all, at least not for the single post.

const action$ = sources.HTTP
    .select('post')
    .flatten()
    .map(res => actions.receivePostById(res.body.id, res.body));

That makes the trick, but I will have to understand better cycle for more advanced stuff anyway.
Thank you again!

@lmatteis
Copy link
Member

lmatteis commented Feb 27, 2017

Yeah if you don't need the post info in the stream, then you don't need combine 😃

Anyway in case you need the post this should work:

import sampleCombine from 'xstream/extra/sampleCombine'

const action$ = response$
  .compose(sampleCombine(post$))
  .map(([ response, post ]) => actions.receivePostById(post, response.body))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants