2

I'm looking for a way to fire an action from inside a callback. I know this is not possible by default, but I'm looking for a way around. Channels are a bad solution in my case (for so far I see it).

The library I use is react-native-ble-plx. In that library, there is a function to start scanning: startDeviceScan(UUIDs, options, listener).

To keep this clean, I want to disconnect the start/stop scan from the listener (hence channels are out of the question).

Before I had this solution:

const onScanChannel = () => eventChannel(emit => {
  BleService.startDeviceScan(..., ..., (peripheral) => {
      emit(peripheral);
    }
  );

  return () => {BleService.stopScan();}
});

The problem is that this connects the channel with the start and the stop of the scan. Which causes you to connect a lot of sagas because you need to start and stop the scanning from application logic (cancel the channel, setup again, start a new saga to listen to the new channel, etc)

What I had in mind is using sagas as normal generator functions:

const startScanSaga = function* () {
  BleService.scan(..., ..., (peripheral) => {
    const generator = deviceFoundHandler(peripheral);
    generator.next();
    generator.next();
  });
};

const deviceFoundHandler = function* (peripheral) {
  yield put(actions.deviceFound(peripheral));
};

That way, the saga for listening to the found-device-actions can just keep running. But, although the put is executed correctly, no take ever receives the action, which suggests that put does not work without the saga-logic behind the scenes.

Does someone know more about this? Or does someone has an alternative approach to realize this?

Thomas Stubbe
  • 1,945
  • 5
  • 26
  • 40

1 Answers1

2

I managed to fix the problem by using middleware.run(saga, ...args).

I needed to export the sagaMiddleWare: export const sagaMiddleware = createSagaMiddleware();

import {sagaMiddleware} from '.../file-where-sagaMiddleWare-is-exported';

const startScanSaga = function* () {
  BleService.scan((peripheral) => {
    sagaMiddleware.run(deviceFoundHandler, peripheral);
  });
};

const deviceFoundHandler = function* (peripheral) {
  yield put(actions.deviceFound(peripheral));
};

Works like a charm =)

Thomas Stubbe
  • 1,945
  • 5
  • 26
  • 40