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)
}
}