Home > front end >  Redux-Saga effects.put callback
Redux-Saga effects.put callback

Time:12-12

I am implementing watch geolocation feature in my React Native app with help of @react-native-community/geolocation and I create an initialize saga function which is responsible for starting the geolocation.watchPosition. I want to pass an redux saga callback function which will update my redux state but it doesn't trigger that callback onGeolocationGet function:

function* initialize(): SagaReturnType<any> {
  try {
    yield effects.call(geolocation.watchPosition, function* onGeolocationGet(data) {
      yield effects.put(UserActions.updateCurrentLocation({ ...data.coords }))
    })
  } catch (err) {
    console.error(err)
  }
}

Thank you mates in advance!

CodePudding user response:

Not a redux saga expert but I believe based on this example on stack over flow, that you don't need to call the function i.e no

effects.call

    function* initialize(): SagaReturnType<any> {
  try {
    yield (geolocation.watchPosition, function* onGeolocationGet(data) {
      yield effects.put(UserActions.updateCurrentLocation({ ...data.coords })
    })
  } catch (err) {
    console.error(err)
  }
}

CodePudding user response:

Not every generator is a saga - like in your case, the saga library has no idea that it should process the generator you pass to watchPosition as a callback.

For callbacks that are called repeatedly, you will want to use the eventChannel utility. It allows you to emit data that are put into a custom channel. You can then listen on this channel using the various take effects.

import {eventChannel} from 'redux-saga'

function createGeolocationChannel = () => eventChannel(emitter => {
  const watchId = geolocation.watchPosition(data => {
    emitter({ ...data.coords });
  });
  return () => geolocation.clearWatch(watchId)
})

function* initialize(): SagaReturnType<any> {
  try {
    const geoChannel = yield effects.call(createGeolocationChannel);
    yield effects.takeEvery(geoChannel, function*(coords) {
      yield effects.put(UserActions.updateCurrentLocation(coords));
    })
  } catch (err) {
    console.error(err)
  }
}
  • Related