'How to "yield put" in redux-saga within a callback inside yield?

I'm having the following problem, my idea is to use CodePush within an application that has redux-saga integrated, the problem I have is that I'm using the following library ('https://github.com/geof90/react-native-code-push-saga') which is great for this implementation

export function* init() {
  try {
    yield put(setShowLoading(true));
    yield spawn(codePushSaga, {
      codePushStatusDidChange: (status) => {
        let nextText = '';
        switch (status) {
          case codePush.SyncStatus.CHECKING_FOR_UPDATE:
          case codePush.SyncStatus.AWAITING_USER_ACTION:
            nextText = 'Checking for Updates...';
            break;
          case codePush.SyncStatus.DOWNLOADING_PACKAGE:
            nextText = 'Downloading Update...';
            break;
          case codePush.SyncStatus.INSTALLING_UPDATE:
            nextText = 'Installing Update...';
            break;
          default:
            break;
        }
        yield put(loadingMessage(nextText)); 
        /* 
        This is the problem because you can't call yield put inside another saga, I have next error
        A 'yield' expression is only allowed in a generator body.ts(1163)
        */
      },
      codePushDownloadDidProgress: (progress) => {
        console.log({
          progress,
        });
      },
      syncOptions: {
        installMode: codePush.InstallMode.IMMEDIATE,
        deploymentKey: codePushDeploymentKey,
      },
    });
  } catch (error) {

  }
}

If we see the function, the codePushStatusDidChange method is a callback that returns the possible states of code push, is it possible to do a put inside another saga?

My idea is for each status change, to do a kind of dispatch to update an example message Checking for Updates... when it is CHECKING_FOR_UPDATE, Downloading Update... when it is DOWNLOADING_PACKAGE, and so on.

I have been researching the documentation of redux-saga and I have found something that refers to channels, https://redux-saga.js.org/docs/advanced/Channels/ but I can't fully understand it,

Could someone help me, I would be very grateful if you can add a code example to understand, thank you very much in advance



Solution 1:[1]

All sagas are generator functions, so you can absolutely put from inside a saga. The issue is that you have changed scope to an arrow function, which cannot use yield. There are a couple ways to get around this.

  1. Rewrite the arrow function as a generator.
codePushStatusDidChange: function* (status) {
  1. Pass in the regular dispatch function as an argument to the action that starts this function. This solution is not great because it involves putting non-serializable values into the redux ecosystem, which should be avoided as a rule of thumb. It also is a bit more complicated. If you think it's the only option for you, I can show a code example for this.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Abe