-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
createAction doesn't support a meta
attribute
#148
Comments
Yep, and it doesn't support customizing |
The two main questions are how The obvious inspirations here would be: https://redux-actions.js.org/api/createaction#createactiontype-payloadcreator-metacreator https://github.com/ericelliott/autodux#action-creators Based on that, I'm thinking roughly: type PayloadCreator = (...args) => Payload;
type MetaCreator = (...args) => Meta;
createAction(
type : String,
payloadCreator? : PayloadCreator ,
metaCreator? : MetaCreator ,
)
createSlice(
reducers: {
simpleReducer: ReducerFunction,
complexReducer: {
payload? : PayloadCreator ,
meta? : MetaCreator ,
reducer : ReducerFunction
}
}
) Actual TS types to be figured out, of course, but you get the idea. |
I'm just exploring options right now. Would something like type PrepareAction<OriginalPayload, Payload, Meta> = (originalPayload: OriginalPayload) => {payload: Payload; meta? : Meta}
createAction(
type : String,
prepare?: PrepareAction,
)
createSlice(
reducers: {
simpleReducer: ReducerFunction,
complexReducer: {
prepareAction: PrepareAction,
reducer : ReducerFunction
}
}
) also be acceptable? That could be way easier to type. |
How do we currently workaround the inability to customise the payload with arguments? This seems like an extremely crucial missing feature. Almost every reducer I have needs the payload to be adjusted based on the function parameters. For example, a reducer that opens an error message snackbar and displays a message. The message can't be hardcoded into the action creator as obviously the error message changes based on what the actual error is. Or a very common case - saving form input values to state. |
Fixed by #149 and out as 0.6.3 . Please let me know if that works for you! |
I've seen how "prepare" works but i'm trying to add parameters to "meta" without having to use "payload", i'm doing this to make it work: const teamsSlice = createSlice({
slice: 'teams',
initialState,
reducers: {
loadTeams: {
reducer: (state: TeamsState) => {
state.loading = true
},
prepare: (payload?: any) => ({
payload,
meta: {
request: {
endpoint: '/teams'
}
}
})
}
}
}); I want to create that action: {
type: 'teams/loadTeams',
meta: {
request: {
endpoint: '/teams'
}
}
} It's possible to do this in |
@jonatanpineda : not quite sure what you're asking here. You don't have to declare any arguments for the |
@markerikson I'm just looking to create an action with the meta property using but an error is generated: so when i add the payload argument all works: but the final object that i want to create doesn't have payload, i only want to produce this: {
type: 'teams/loadTeams',
meta: {
request: {
endpoint: '/teams'
}
}
} how to achieve this correctly? |
It may be because you're not declaring a type for the action object in the reducer. Then again, it might be that we need to improve our TS types somehow. |
I'm sorry I didn't show all the error: Type '{ reducer: (state: TeamsState) => void; prepare: () => { meta: { request: { endpoint: string; }; }; }; }' is not assignable to type 'CaseReducer<TeamsState, any> | EnhancedCaseReducer<TeamsState, any>'. I typed the action with 'AnyAction' in the reducer and the error persists: Probably the project needs to enable that feature, I think it's necessary because of the simplicity of |
Okay, I just added #176 to track this. |
Stick with that workaround for now. We'll try to get the TS types updated in the near future to allow returning just Note that you should be able to at least skip having |
@jonatanpineda : after thinking about it further, I've closed #176 . I feel that the |
I'm wondering why adding that restriction and not simply just send the object that the prepare function returned with all of it's properties (meta, error, etc.). This is kinda contradictory to this part of the documentation:
|
@0w3w : We added support for the The point is that the FSA spec only allows |
I agree that only FSA properties should be allowed, then, Is there any reason why those properties are not available on the case reducers? I think they should. Accessing error and meta information on the reducer is something I've seen on several projects and is very useful when using FSA. E.G.
Am I missing something? Also, Kudos for the super quick response! |
Those properties will be accessible, so I'm not sure why you're saying they're not. That's one of the reasons why we made sure to continue passing the entire |
@0w3w You always need to type import {createSlice, PayloadAction} from '@reduxjs/toolkit'
export const doSomethingSlice = createSlice({
name: 'dosomething',
initialState: { foo: "bar"},
reducers: {
DoSomething: {
reducer: (state, action: PayloadAction<undefined /*payload*/, string /*type*/, string/*meta*/>) => {
console.log(action.meta);
},
prepare: () => ({ payload: undefined, meta: "something" })
}
}
}); |
@phryneas Bravo! That is what I was missing! |
@phryneas : hmm, not sure I was aware of that. I don't think we've got it covered in the "Usage with TS" page. |
Good point. There's no |
Ah, I see why looking at the type-tests. There I'm only testing the payload and that is just typed exactly as the case without My assumption was that the reducers only access the |
…tional FSA properties (meta & error) (reduxjs#148)
Hey, so I stepped into another TS error with this: With error:
I think the problem is that the SliceCaseReducer type I forked and tried to fix this by adding additional supported types: export type SliceCaseReducers<State> = {
[K: string]:
| CaseReducer<State, PayloadAction<any>>
| CaseReducerWithPrepare<State, PayloadAction<any>>
| CaseReducerWithPrepare<State, PayloadAction<any, string>>
| CaseReducerWithPrepare<State, PayloadAction<any, string, any>>
| CaseReducerWithPrepare<State, PayloadAction<any, string, any, any>>
} But, while my changes fix the issue, it breaks types.test.ts on inferred types:
Here is my proposed change with updated documentation and a test for it. I didn't create PR cause the tests are not passing. Any guidance on this? |
This doesn't error for me in this sandbox: https://codesandbox.io/s/brave-sky-ulhsx Could you create me a reproducible? I'd like to see the actual error before discussing a possible solution ;) |
I'm using strict type checking, changed tsconfig.json to:
Then the error shows. The project is configured with strict type-checking As a temporary workaround disabling strictFunctionTypes on the tsconfig fix this error. |
Sorry, I somehow didn't see your message earlier. The thing is, the example I linked to you has {
"compilerOptions": {
"module": "commonjs",
"jsx": "preserve",
"esModuleInterop": true,
"sourceMap": true,
"allowJs": true,
"strict": true,
"lib": [
"es6",
"dom"
],
"rootDir": "src",
"moduleResolution": "node"
}
} So there's gotta be some other difference? |
Here's a code sandbox with a reproducible error: I just need some guidance and I may be able to fix it on my branch and create a PR ;) Also this seems like a new error for this thread, should I create a new Issue? |
And as far as I can tell there is no way to possibly insert it.
not a big deal, any action that has meta attributes, you can just manually create.
If I were to make a proposal, it would be that it would be a second argument.
The text was updated successfully, but these errors were encountered: