question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to use yield call() from an external API callback?

See original GitHub issue

Hello!

I’m using an external API (Firebase), which uses callbacks. I’m not 100% sure what’s the best approach to converting the callbacks to something usable by redux-saga because of its use of generators.

Code:

    const database = firebase.database();
    const connectionRef = database.ref('.info/connected');
    connectionRef.on('value', (snapshot) => {
      if (snapshot.val() === true) {
        yield call(actions.connected);
      }
    });

Action:

    export const connected = () => {
      return {
        type: types.FIREBASE_CONNECT,
      };
    };

Reducer:

    const connectionStatus = (state: boolean = initialState, action: Object) => {
      switch (action.type) {
      case types.FIREBASE_CONNECT:
        return true;
      default:
        return state;
      }
    };

I can’t use yield because the callback isn’t a * generator function.

What’s the correct approach to converting it in a manner that’s good for redux-saga to handle?

BTW, I’ve really been enjoying redux-saga- it’s been fantastic to use, thanks!

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:22
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

67reactions
aikovencommented, Aug 30, 2016

You can wrap your code to a function that returns promise, something like

function connect() {
  return new Promise(resolve => {
    const database = firebase.database();
    const connectionRef = database.ref('.info/connected');
    connectionRef.on('value', resolve);
  });
}

Then use it in saga:

const snapshot = yield call(connect);
if (snapshot.val() === true)
  yield put(actions.connected());
25reactions
Andaristcommented, Aug 30, 2016

@aikoven this Promise will resolve just once, if he wants to get multiple values over time from the firebase callback it is not a suitable solution unfortunately

what i came up with in my project is that - https://github.com/yelouafi/redux-saga/issues/475#issuecomment-239129811

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to yield inside an external callback function in react redux ...
Call Channel const msg = yield take(chan); // 2. Wait for channel to emit a message // Rest of code... (Add error handling...
Read more >
API Reference - Redux-Saga
The result of yield take(pattern) is an action object being dispatched. If it is a function, the action is matched if pattern(action) is...
Read more >
Making async reasonable with redux saga
Yield. Async example with callbacks. api.get(URL, function callback(data){ ... Code tends to grow vertically with additional “then” calls.
Read more >
OpenAPI Callbacks - FastAPI
The process that happens when your API app calls the external API is named a "callback". Because the software that the external developer...
Read more >
yield - JavaScript - MDN Web Docs - Mozilla
yield can only be called directly from the generator function that contains it. It cannot be called from nested functions or from callbacks....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found