redux-saga: How to create multiple calls/side-effects programmatically for yield?
Asked Answered
H

3

14

With redux-saga, one can execute multiple effects in parallel:

import { call } from 'redux-saga/effects'

// correct, effects will get executed in parallel
const [users, repos]  = yield [
  call(fetch, '/users'),
  call(fetch, '/repos')
]

How can i create those "call"-calls programmatically?

What i want to achieve is this:

Lets say i have an array with different parameters and i want to execute a request to a server per parameter, but in parallel with redux-saga:

const parameters = ['abc', 'def', 'ghi']

const allMyFetchCalls  = parameters.map( (p) => makeCallRequestWithParameter(p) );

makeCallRequestWithParameter would create a function call (or in redux-saga-speech: an effect) call(fetch, param) like in yield call(fetch, param)

const resultArray = yield allMyFetchCalls;

Is this possible and if so, how?

Hervey answered 14/10, 2016 at 12:51 Comment(0)
M
22

Please note that call effect doesn't call anything at the time. It just creates Plain JavaScript Object and returns. So what you want is not so difficult.

import { call } from 'redux-saga/effects'

const params = ['abc', 'def', 'ghi']
const responses  = yield params.map(p => call(fetch, p))
Middlebreaker answered 14/10, 2016 at 13:13 Comment(3)
Wow! Thank you very much!Hervey
will it be concurrent or not?Jeepers
it's concurrent.Middlebreaker
J
11

So according to the redux saga docs as of 11/17/2019 its says in order to make it execute in parallel you need to use all()

yield all( arrayOfSomething.map( eachSomething => call( myFunction, eachSomething ) ) )

or if you want to compute some stuff before making your call

yield all( arrayOfSomething.map( eachSomething => {
   // do some computations

   // important you return the function which is automatically done 
   // for you in the one line map, this has gotten me a few 
   // times when I am just coding fast
   return call( myFunction, eachSomething ) )
} )
Jolinejoliotcurie answered 7/11, 2019 at 13:32 Comment(0)
D
7

This might work aswell https://github.com/redux-saga/redux-saga/tree/master/docs/api#alleffects

function* mySaga() {
  const { customers, products } = yield all({
    customers: call(fetchCustomers),
    products: call(fetchProducts)
  })
}
Delaminate answered 10/10, 2017 at 15:12 Comment(3)
works when all requests are successful but throws error even if a single call is failed. I want to get the response of all requests even if some fails. how to do it?Jeepers
@VikasBansal Bit late to the party. Did you find a solution for this?Physicality
Found a solutionPhysicality

© 2022 - 2024 — McMap. All rights reserved.