Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use select effect in normal function/eventChannels

Tags:

redux-saga

I am using redux sagas event channel. I have a specific use case where i want to getStore state when event gets triggered as eventChannel is not generator function i am not able to use select effect of redux sagas. Any other way to achieve this ?

I had also tried to import store and use store.getState() but i am getting undefined as saga file is imported before store gets initialized.

function subscribe(socket) {
    return eventChannel(emit => {
        socket.subscribe(listenerTopic, {qos: 1});
        socket.on('reconnection', () => {
            // i need to fetch latest unread message, for that i need to get timestamp
           // for last message received which is in store so the command will be to 
         // send sinceDate i.e last message timestamp and untilDate that is currentDate
   })
}
like image 725
Priyank Bhatt Avatar asked Apr 05 '17 16:04

Priyank Bhatt


People also ask

What is the use of takeEvery in Saga?

In the above example, takeEvery allows multiple fetchData instances to be started concurrently. At a given moment, we can start a new fetchData task while there are still one or more previous fetchData tasks which have not yet terminated.

Can we use fork with race?

The fork effect always wins the race immediately. On the other hand, fork effects in a race effect is most likely a bug. In the above code, since fork effects are non-blocking, they will always win the race immediately.

Why is select method used in redux-saga?

a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage. The select effect is just used to get a slice of the current Store's state .

Is redux-saga deprecated?

Such a powerful & elegant tool as Redux-Saga, a Redux side effect manager, is said to be deprecated, and no longer being maintained, starting from Jan 27, 2021.


1 Answers

One possible solution would be to use redux-saga channel feature. The idea would be to push an event into the channel each time a socket event occurs. At the same time you have another saga listening for events on the channel and reacts accordingly. Because the listening part is a saga, you can use common saga effects like select.

Your code could probably look like this:

import { channel } from 'redux-saga'
import { select } from 'redux-saga/effects'

const socketChannel = channel()

function subscribe(socket) {
  return eventChannel(emit => {
     socket.on('reconnection', () => {
       socketChannel.put({ type: RECONNECTION })
     })
  })
}

export function* watchSocketChannel() {
  while (true) {
    const action = yield take(socketChannel)

    if (action.type === RECONNECTION) {
      const lastMessageTimestamp = yield select(selectors.getLastMessageTimestamp)
      ...
    }
  }
}

I hope this will help you.

like image 133
Alex Avatar answered Sep 28 '22 03:09

Alex