Redux Middleware, Promise or Thunk - redux

I'm using Redux Thunk as middleware for Async call, but I have seen examples that use Redux Promise, what are the differences, between these middlewares.

Both redux-thunk & react-promise delay dispatching at the suitable time .
However there are some points of difference :
1. When it intervenes :
react-thunk intervenes when the action creator returns a function, not a literal object .
react-promise intervenes when the action creator still returns an action (literal object ) but this action must have property payload, and the value of this payload is a promise (instance of Promise).
2. Who is the last dispatcher :
redux-thunk : You are the last dispatcher, reach-thunk just gives you access to dispatch function as an argument of the function (that is returned by action creator)
redux-promise: It will takes the promise (in the payload property) and dispatch the same action type in the then block , but it replaces the payload of the action with the response (the argument of then block ).

Related

Testing reducer with createAsyncThunk rejected actions

Currently, I am using v1.4.0 of #redux/toolkit and when I am testing a reducer using a rejected action created through a createAsync thunk with a custom rejectedWithValue. The action object can be created with a custom error payload like
asyncThunkAction.rejected(null, '', undefined, {
message: 'error',
errorCode: 500,
});
with v1.5.0 you are no longer able to pass in the 4th error argument.
How are you able to test the behaviour of the slice with the rejected action containing the rejectedWith payload?
You can now just pass it in as the first argument.
Please note that this is not a publicly documented API (the action creators are on there only for matching and accessing the error type) and we do not give guarantees for it's stability.

Can I dispatch root actions from feature store in ngrx?

I'm new to ngrx. I'm little confused in dispatching actions.
State:
{
uiState: UIState,
featureState: FeatureState
}
From my feature effects, I need to dispatch a UI action. So I injected Store<State> and dispatch. It worked fine.
But, if I use Store<featureState> and dispatch UI action, this also works fine.
I thought, if I dispatch a UI action from feature store, the store will not know which reducer to call for that action and get a default state. But the value in the uistate is updated.
So, does this mean I can dispatch any action from anywhere?
Yes - you can dispatch any action from anywhere.

Redux: data manipulation is a responsability of the action or of the reducer?

My action fetch an url and got a json.
I need to transform this json into an array of objects and set into the state.
I ask you: Where must placed the business logic to transform json into an array of object?
Must be placed
into the action code dispatching an action with a 'ready-to-use' payload,
or
into the reducers code, which receive the 'raw data' as json in the payload, then transform into an array of objects and put into the state
?
According to the Redux doc
Actions are payloads of information that send data from your application to your store.
Actions describe the fact that something happened, but don't specify
how the application's state changes in response. This is the job of
reducers.
So I will go for the option #2: doing it into the reducers code, which will receive the 'raw data' as json in the payload, then transform into an array of objects and put into the state.
This is an old question, but i would like to share my thoughts. Your situation is referred to as an async action in the redux documents. And while:
Actions are payloads of information that send data from your application to your store.
Actions describe the fact that something happened, but don't specify how the application's state changes in response. This is the job of reducers.
Async actions are a little more complex and as shown in the redux documentation under Advanced Tutorials: Redux Async Actions:
export const RECEIVE_POSTS = 'RECEIVE_POSTS'
function receivePosts(subreddit, json) {
return {
type: RECEIVE_POSTS,
subreddit,
posts: json.data.children.map(child => child.data),
receivedAt: Date.now()
}
}
They suggest you parse the async response before you send it to the reducer. So i think option 1 is the correct one.
Hope this helps!

What data types can be passed to redux-thunk actions?

Problem overview
I am using redux-form, and it wraps my compoent, and provides as a property change() which is a bound function for changing the form. I wanted to invoke this in an actionCreator.
Issue
I thought I could just pass it to my actionCreator thunk, but it seems that the value is stripped on dispatch of the action.
Details
So what I tried instead of sending the bound action change I tried instead to send a pointer to one of my other actionCreators called act.setFMEPATH, but that is also not working.
In the first picture below I show the state of the variables in before the dispatach to the redux-action occurs. As you can see from the watch, act.setFMEPath clearly is defined.
In the second picture you see the state of the action when it is entered. defaultPath is define (it is scoped to a closure on the stack), but the storeAct.
In my code, I am hard coding the STORE.dispatch(Act.setFMEPath(filePath[0]) since the paramater storeAct is not visible, But what I want it STORE.dispatch(storeAct(filePath[0])
Should I be binding the context of the first parameter to the dispatch() and turning storeAct() into a bound function (but note it is an arrow function, so that is not going to work).
State before call:
State entry of pickFile action creator
The code which invokes pickFolder (i.e. Act.pickFolder(Act.setSourcePath, defaultPath)) has nothing to do with redux-thunk at all. It will be evaluated before redux-thunk will come into play, because of the way redux-thunk works.
redux-thunk checks if dispatched value was a function and if it was, redux-thunk invokes it with dispatch, getState and extraArgument params. Please check its source code, it's really tiny and simple.
Basically it means exactly what Radio said: if it's undefined in pickFolder that's because it was undefined in the caller. Also I don't see any usages of destination in your pickFolder, so maybe check for the typos.
It seems that redux is not happy with not plan javascript object. As shown above, when I tried to dispatch an actionCreator which had a bound function call as a parameter, it was missing when the actionCreator was created.
I also tried to create a reducer that placed a function handle (bound function) into the store, and it was not stored, and the prior value was removed (a placeholder).
I am puzzled by what #Radio- is saying, since what I am seeing is that redux does not like things that are not plain javascript objects (either as parameters to the dispatch call, or as values from the reducer to be placed in the store).

How to trigger a single initial action in many redux reducers at once?

I am refactoring my app to use redux, and it's great.
One thing I'd like to do is to dispatch an initial action at the beginning, and every reducer would manage to initialize themselves at that moment.
Let's say i have a main.js that create the stores, the routes, etc. In that file, I could do:
store.dispatch({ type: 'app/init' });
If I do this, the action type app/init can be intercepted in each reducer which needs to initialize itself.
An example use case (among others)
When the app is launched, a third party library must be called to see if a user is currently authenticated. If so, a LOGIN_SUCCESS action must be triggered with that user data.
I'd like to see this code in the same file as the authentication reducer, triggered by a global init action (which would mean the store is created).
The problem
In the reducer (where init action is managed), other actions cannot be dispatched.
The advised way of implementing actions is by defining action creators, which is indeed very clean, and let us use middleware like thunks to dispatch other actions.
I could use init() action creators for each reducer (I define related actions and reducer in the same "ducks" file), but that means importing/calling each of them in main.js, which is what I was trying to avoid by dispatching the action directly.
How to get the best of all worlds by having one single app/init action dispatched, and being able to intercept it in each store and dispatch other actions?
Note: I thougth of just implementing those initialization code in each reducer, inline, but I do not have standard access to the dispatcher that way?
The reducer just calculates the next state based on an action. In Redux, it’s not the right place to put side effects like calling an API.
If you want to orchestrate an asynchronous workflow of actions, I suggest you to look at Redux Saga. It lets you define long-running functions (“sagas”) that can “wait” for specific actions, execute some side effects, and dispatch more actions.

Resources