Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 24 09:25
    floroz edited #757
  • Oct 24 09:25
    floroz edited #757
  • Oct 24 09:25
    floroz opened #757
  • Oct 10 09:29
    omerts edited #756
  • Oct 10 09:29
    omerts opened #756
  • Oct 10 09:27
    omerts closed #755
  • Oct 10 09:24
    omerts opened #755
  • Oct 09 12:05
    MursalovAltun commented #706
  • Oct 08 12:25
    Whazor commented #706
  • Oct 05 14:56
    evertbouw commented #752
  • Oct 04 13:19
    andrevmatos commented #754
  • Oct 02 17:00
    talhaguy commented #752
  • Oct 02 06:42
    talhaguy commented #752
  • Oct 01 21:57
    andrevmatos closed #754
  • Oct 01 21:57
    andrevmatos commented #754
  • Sep 30 21:45
    andrevmatos edited #754
  • Sep 30 18:54
    andrevmatos edited #754
  • Sep 30 18:53
    andrevmatos opened #754
  • Sep 23 11:43
    innovation-stack opened #753
  • Sep 18 22:15
    D34THWINGS commented #752
Eleonora Lester
@elstr
but can't manage to make it work
Jesus The Hun
@JesusTheHun
@elstr show me what you got I'll help you do that
Kevin Ghadyani
@Sawtaytoes
@saharrachamimfg No clue. I wrote an article about how you could use it, but each app is different. Just know you can and should dispatch actions from epics that trigger other epics.
@xieshuhong can you paste the code and the issue you can't solve?
@JesusTheHun Correct. I catch those and dispatch different actions based on success or failure.
mwalkerr
@mwalkerr
The JSbin link on https://redux-observable.js.org/docs/basics/Epics.html isn't working because JSbin is asking for a pro account to embed from https
Kevin Ghadyani
@Sawtaytoes
I wonder if all of them are like this. @jayphelps Looks like the site might need to use another paste-bin service or a license needs to be paid.
PogoniiA
@PogoniiA
Hey guys
Is there a way in epic to subscribe for continuos data fetching
to listen changes in firebase ?
Pervez Alam
@pervezalam777
@PogoniiA : Yes, I think so, if you can open a request which keep on sending data then it can be done. Server sent event is the way to handle this please go through https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events Also I have create on sample for the same https://github.com/pervezalam777/server-sent-event (NOTE: Redux-Observable not used in this example)
PogoniiA
@PogoniiA
@pervezalam777 thanks. I found a good example on stackoverflow which covers my whole idea.
So if someone is interested :
https://stackoverflow.com/questions/40983206/how-to-eventsource-with-redux-observable
Kevin Ghadyani
@Sawtaytoes

@PogoniiA The answer in that StackOverflow link is correct.

Because Firebase doesn't have a native RxJS implementation, you need to take their streaming function, wrap it in an RxJS observable, and pipe off that in Redux-Observable.

From there, it just dispatches actions and the rest of your code works as you'd expect.

amir
@amirbr

Hello guys,
I'm trying to test my Epic, I'm quite new with TestScheduler and Marble Diagrams.

I hope someone can help.

this is my Epic:

const deleteMediaEpic: Epic = (actions$, state$: StateObservable, { api }: EpicDependencies) =>
  actions$.pipe(
    ofType(DELETE_MEDIA),
    switchMap((action: DeleteMediaAction) => api.deleteMedia(action.payload.operationCode, action.payload.productKey, action.payload.mediaToDelete).pipe(
      switchMap(() => {
        const actionsToDispatch = []
        actionsToDispatch.push(productSelected(action.payload.productKey, action.payload.operationCode))
        actionsToDispatch.push(clearMediaSelected([]))
        return of(...actionsToDispatch)
      }),
      catchError(mediaFetchError => of(`Error in deleteMediasEpic: ${mediaFetchError}`))
    ))
  )

and this is my test:

it('Delete select Media', () => {
  testScheduler.run(({ hot, cold, expectObservable }) => {
    const action$ = hot('-a', {
      a: { type: 'DELETE_MEDIA', payload: { productKey: 'PRODUCT_KEY1', operationCode: 'VPV_H_SHANAOR1', mediaToDelete: [0] } }
    })

    const state$ = {}

    const dependencies = {
      getJSON: url => cold('--a', {
        a: { url }
      })
    }

    const output$ = deleteMediaEpic(action$, state$, dependencies)

    expectObservable(output$).toBe('---bc', {
      b: {
        type: 'PRODUCT_SELECTED',
        payload: { productKey: 'PRODUCT_KEY1', saleCode: 'VPV_H_SHANAOR1', filtersType: undefined }
      },
      c: {
        type: 'CLEAR_MEDIA_SELECTED',
        payload: {
          defaultValue: []
        }
      }
    })
  })
})

for me of is a sequence operator and c should be immediately after b.

Hope you can understand something from the code me.

and this is the result of the test:

  expect(received).toEqual(expected) // deep equality

  - Expected
  + Received

  @@ -1,8 +1,8 @@
   Array [
    Object {
  -   "frame": 3,
  +   "frame": 6,
     "notification": Notification {
      "error": undefined,
      "hasValue": true,
      "kind": "N",
      "value": Object {
  @@ -14,11 +14,11 @@
       "type": "PRODUCT_SELECTED",
      },
     },
    },
    Object {
  -   "frame": 4,
  +   "frame": 6,
     "notification": Notification {
      "error": undefined,
      "hasValue": true,
      "kind": "N",
      "value": Object {

     5 | 
     6 | const testScheduler = new TestScheduler(
  > 7 |  (actual, expected) => { expect(actual).toEqual(expected) }
      |                      ^
     8 | )
amir
@amirbr
I found it, I need to group my action like this ------(ab) because I use of or from
Kevin Ghadyani
@Sawtaytoes
@amirbr Glad you figured it out. I meant to respond yesterday and got caught up in other things.
amir
@amirbr
Thank you @Sawtaytoes
Tommy Asz
@ThomasEddie
any have an example of redux-observable with typescript? it really complicated when using typescript
Kevin Ghadyani
@Sawtaytoes
@ThomasEddie I've personally not used TypeScript with Redux-Observable. What are the issues you're running into.
Alexander Riss
@alexander-riss
Hi all - very basic question - is it possible for two epics to listen for the same action without conflicting ?
20 replies
André Samuelsson
@Tejpbit

@ThomasEddie
I've been battling with redux-observable and typescript for a couple of hours now and I'm finally up and running.
I strongly suggest using redux-toolkit if you haven't done so before. https://redux-toolkit.js.org/
They have a very small example here: https://redux-toolkit.js.org/api/createAction#with-redux-observable
This is what worked for me, but I've been using redux-toolkit for a couple of projects now so this step was pretty natural I guess.

Before getting that working I mucked about with typesafe-actions since that was what examples I found was using. It was type-hell. From my short hours of that, I suggest not having typesafe-actions and redux-toolkit in the same project. They want to do the same thing.

I also had a look at this example repo: https://github.com/mitsuruog/react-redux-observable-typescript-sample
which does redux-observable with typesafe-actions. Looks very decent. The import * as actions from '...' thing here https://github.com/mitsuruog/react-redux-observable-typescript-sample/blob/master/src/shared/store/index.ts#L6
forces you to split your actions to its own file with nothing else in them, which is a good habit to have.

Here's my redux store setup for inspiration:

import {combineReducers, configureStore, Action, createAction} from "@reduxjs/toolkit";
import { combineEpics, createEpicMiddleware } from "redux-observable";
import { filter, map } from "rxjs/operators";

import { Observable } from "rxjs";

export const ping = createAction<{ foo: string }>("ping");
export const pong = createAction<{ bar: string }>("pong");

const epicMiddleware = createEpicMiddleware();

const epic1 = (action$: Observable<Action>) =>
  action$.pipe(
    filter(ping.match),
    map((a) => pong({ bar: a.payload.foo.toUpperCase() }))
  );

const rootEpic = combineEpics(epic1);

const rootReducer = combineReducers({
  // your reducers
});

export const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(epicMiddleware),
});

epicMiddleware.run(rootEpic);

export type RootState = ReturnType<typeof rootReducer>;
Kevin Ghadyani
@Sawtaytoes
@Tejpbit Instead of filter(ping.match), why not use ofType(ping.type)?
André Samuelsson
@Tejpbit
image.png
Just tried it.
Looks like the filter with action.match thing makes sure the next operations in the pipe are typed.
With ofType the rest of the types of the members on the action is not deduced.
Most likely because I'm using the redux-toolkit action creators. If I would be using the typesafe-action action creators and then also set the type of the action using the Epic from redux-observable with all its type parameters then the ofType way would work, I think.
Jānis Zaržeckis
@jzarzeckis

Probably this is not the right place to ask such an off-topic question - but I'm wondering is Redux Observable still a popular choice among developers?

I personally like it quite much, but perhaps now there are some better alternatives. I see people keep using redux-sagas - but I personally can't really stand them.
And some avoid redux in the first place, therefore use just hook libraries such as https://www.npmjs.com/package/rxjs-hooks

Just curios to hear some opinions about some popular options post redux-observable

1 reply
Kevin Ghadyani
@Sawtaytoes

@jzarzeckis Great question! One I've pondered myself since I started using it. RecoilJS argument at the bottom.

Redux-Observable is very niche in terms of who's using it, but it brings an amazing amount of value to a project. I will absolutely use it on any project I write myself and just got my place of employment to start using it. The biggest complaint is the lack of documentation (for it an RxJS) whereas I've heard how much simpler the epic model has been. We could achieve the same thing writing custom middleware, but it wouldn't be in these slick functional pipelines that RxJS provides.

Redux-Observable is Message-Oriented Programming. This is by-far, one of the best ways to build projects. If you look at engineers that work on backend services, they're going more and more for a distributed model of micro services with an event bus and a standard interface between machines. It's not just machines talking to machines, there's usually a broker somewhere like RabbitMQ, Redis, or Kafka in the middle handling the publishing and subscribing of micro services to the services they care about. Sound familiar? It's the same as ofType in Redux-Observable.

Many developers get bored with old tech (myself included). The reason React is still in vogue happens to be because the component API fundamentally changes ever year. People have to keep making tutorial videos, writing articles, and complaining about it. It sells itself. Svelte would've taken over if not for hooks as it's a lot easier to understand and works on the same observable model as hooks.

Redux has been falling out of favor because React hooks are more convenient the same way imperative code is right there in the language and RxJS is not. Sadly, React hooks are messy, impossible to unit test unless you pull them into a separate hook, and easy to wind up with serious performance problems (one reason why RecoilJS exists). There are other reasons like Redux is falling out of favor, but I attribute it to the fact that nothing really changes; therefore, no one really talks about it. Where I work, we decided to keep using Redux going forward and are even using it more now; although, we don't agree with the single-store model and have changed that methodology too.

The reason RecoilJS isn't a replacement for Redux-Observable is because it doesn't have a single event bus. Every observable or atom is watching other observables for changes. If you've ever written an RxJS application without Redux-Observable, you probably know how complicated this can be. It won't take long for people to have no clue what the business logic is doing. Having a single event bus (Redux) makes everything easier at a small potential cost to performance.

On top of that, RecoilJS is like writing Redux middleware without RxJS. It uses its own observable model and is ultimately just a way around React Context API. Heck, we had the same issue with React's context at work on multiple occasions. We even built our own form library to handle it.

Jānis Zaržeckis
@jzarzeckis
@Sawtaytoes your answer is candy to my ears
Ghost
@ghost~601d65c86da03739846130df
I'd like to learn more through community.
Cvetkovic Milos
@cveksitron_twitter
@Sawtaytoes I do like redux observables, I'm coming from Angular word- there is the same paradigm as ngrx but I'm missing the lazy load store item feature, any advice from you on how I can lazy load them in combination with redux-observable, I've found some Microsoft's library called redux dynamic modules but it's not so popular, I'm asking because in large project initial scripting will be to big, thanks in advanced :)
5 replies
Phudit Chuengjaroen
@nuttikung

Hi Everyone, I have a question regarding RXJS and Redux Obs.

I would like to make the epic for fetching data when user comes to /public/:id then if user leave and data comes later for next time user go in the same path(different id) user still see the last then loading
So my questing do I need to use Cancellation on switchmap ? because I have tried and after user go in the same path it’s not fetching anymore.

Alessandro Savino
@xavier7179
@nuttikung I could be wrong but you do not need to cancel, otherwise the observable is not "listening" anymore...
Kevin Ghadyani
@Sawtaytoes

@nuttikung switchMap has automatic cancelation in some ways. If it receives the command twice, the first one gets canceled. Or do you mean something like take or takeUntil on your data fetch?

I write in cancelation for all my data fetching, but it's different for each based on the needs of the app. For instance, if the user logs in, does it fire the action again? If so, switchMap is enough. If not, you have to write that in yourself.

Luke
@lukeyxu
Guys I just noticed that the latest Chrome is randomly cancelling my forkjoin requesets, (im not dispatch any cancellation acitons). Firefox/Edge all working fine for me
Please let me know if you run into any similar situation or if you have any possible solutions
Kevin Ghadyani
@Sawtaytoes
Never come across that issue, but it seem very strange that'd happen; especially only in Chrome.
Luke
@lukeyxu
is there anyway to cancel the ajax observable in addition to takeUntil?
check the bottom of that page. you need to do more homework before asking questions
Bo Chen
@bochen2014
hi all
from([1,2,3,4]).pipe( filter(v=>v==2), tap( v=>{ // do something}) , swallowit )
how can I swallow it?
i.e. dont' emit anymore , I see ppl write filter (()=> false)
is there a better approach?
Kevin Ghadyani
@Sawtaytoes
@lukeyxu What are you asking in particular? Are you saying you'd like another method other than takeUntil to cancel an ajax observable. switchMap is one that I use often to do that. If a new message comes into a switchMap, it cancels the previous one.
jsjow
@jsjow
Hi, I'm struggling with observables testing
Can anyone here help ?
Kevin Ghadyani
@Sawtaytoes
@jsjow What is the issue? If you paste some code, most people here could help you write a test for that code. Observable testing can be tough, but testing Redux-Observable epics is fairly simple.
jsjow
@jsjow
Hi, can someone help me with this issue : No reducer provided for key ... whenever I run a test using the actual store
3 replies
jsjow
@jsjow

Hi could someone help me with this : I'm getting an error "no reducer provider for key "somekey" ". I tried many different way of importing and exporting, and this only happens when I run the store using Jest and Enzyme. The code : I'm exporting the reducer like so: export default function connections(state = DEFAULT, action = {}) Then I'm importing like so:
import { connections } from '../redux/modules/connections'; Then I'm using combineReducers: import { combineReducers } from 'redux';

const appReducer = combineReducers({
connections,
}); And them I'm creating the store: function rootReducer(state, action) {
let finalState = appReducer(state, action);

return finalState;
}

const storeGenerator = (initialState) => {
const epicMiddleware = createEpicMiddleware();
let middlewares = applyMiddleware(epicMiddleware);

if (blabla...) {
// additional logging middlewares when running the application in development mode
middlewares = applyMiddleware(epicMiddleware, logger);
}

const store = createStore(rootReducer, initialState, composeWithDevTools(middlewares));
epicMiddleware.run(rootEpic);

return store;
}

export default storeGenerator;