Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call yield in firebase read API

I have a redux saga API, where by I am connecting to firebase and reading records of data.

var roomRef = firebase.database().ref('/Users/' + userid + '/rooms')
  var rooms = []
  roomRef.once('value', function (snap) {
    var roomkeys = snap.val()
    for (var roomkey in roomkeys) {
      firebase.database().ref('/Rooms/' + roomkey).once('value', function (item) {
        rooms.push(item.val())
      })
    }
    console.log(rooms)
   --> put({type: 'LOAD_ROOMS', payload: { rooms: rooms}})
  })

Since my put is inside a callback function I cannot use the yield keyword. How do I dispatch an event to change the state of my reducer with the new values 'rooms'

like image 674
Nick Avatar asked Mar 09 '23 21:03

Nick


1 Answers

The way to work around this is to convert the callback into a promise. redux-saga knows how to resolve promises that you pass to the call effect. But call takes a function, not a promise. From the docs:

If the result is a Promise, the middleware will suspend the Generator until the Promise is resolved, in which case the Generator is resumed with the resolved value. or until the Promise is rejected, in which case an error is thrown inside the Generator.

var roomRef = firebase.database().ref('/Users/' + userid + '/rooms')
var rooms = yield call(function() {
  return new Promise(function(resolve, reject) {
    roomRef.once('value', function (snap) {
      var rooms = []
      var roomkeys = snap.val()
      for (var roomkey in roomkeys) {
        firebase.database().ref('/Rooms/' + roomkey).once('value', function (item) {
          rooms.push(item.val())
        })
      }
      resolve(rooms)
    })
  })
})
yield put({type: 'LOAD_ROOMS', payload: { rooms: rooms}})
like image 187
ctlevi Avatar answered Mar 20 '23 19:03

ctlevi