feathersjs / docs

[MOVED] Legacy Feathers documentation

Home Page:https://crow.docs.feathersjs.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cookbook Suggestion: Handling realtime events on the client side with redux-saga

devashishsethia opened this issue · comments

Comment/Problem

There are not many handy guides around how do you handle real-time events with redux-saga. I had to do a lot of work to get there. I think this can help anyone who is feeling lost.

Setup client (feathers.js)

import AsyncStorage from '@react-native-community/async-storage';
import feathers from '@feathersjs/feathers';
import socketio from '@feathersjs/socketio-client';
import io from 'socket.io-client';
import auth from '@feathersjs/authentication-client';

const socketOptions = {
  transports: ['websocket'],
  forceNew: true,
};
const authOptions = {
  storage: AsyncStorage,
};

const socket = io('http://feathers-server-url', socketOptions);
const client = feathers();

client.configure(socketio(socket, {timeout: 15000}));
client.configure(auth(authOptions));
client.service('payments').timeout = 15000;

export default client;

Set up a watcherSaga

import {take, put, call} from 'redux-saga/effects';
import {eventChannel} from 'redux-saga';
import FeathersClient from '../../feathers';
import {addNewTxn} from 'redux/walletTransactions/actions';
//We're trying to listen for an event when a new transaction is added

// this function creates an event channel from a given socket
function createSocketChannel(feathersClient) {
  // `eventChannel` takes a subscriber function
  // the subscriber function takes an `emit` argument to put messages onto the channel
  return eventChannel(emit => {
    const walletTxnHandler = txnData => {
      emit({type: 'walletTxn', txnData: txnData});
    };

    // setup the subscription
    const walletService = feathersClient.service('wallet-transactions');

    walletService.on('created', walletTxnHandler);

    // the subscriber must return an unsubscribe function
    // this will be invoked when the saga calls `channel.close` method
    const unsubscribe = () => {
      walletService.removeListener('created', walletTxnHandler);
    };
    return unsubscribe;
  });
}

export function* listenForSocketEvents() {
  const socketChannel = yield call(createSocketChannel, FeathersClient);
  while (true) {
    try {
      // An error from socketChannel will cause the saga jump to the catch block
      const socketEvent = yield take(socketChannel);
      switch (socketEvent.type) {
        case 'walletTxn':
          yield put(addNewTxn(socketEvent.txnData)); //dispatch the action with the txnData
          break;
      }
    } catch (err) {
      console.error('socket error:', err);
    }
  }
}

I understand and agree that this is probably not feathers specific. So, please feel free to drop.