Reputation: 461
I just created my sample Redux tool kit with js files. now I am trying to convert them to typescript. some of the error is now fixed. but I have no idea how to fix the two errors below.
Please refer to my comments within the code below and please help me to how to solve the problems
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from "axios";
export interface UserState {
username: string;
email: string;
isFetching: boolean;
isSuccess: boolean;
isError: boolean;
errorMessage: string;
}
interface check {
name: string;
email: string;
password: string;
}
const initialState: UserState = {
username: "",
email: "",
isFetching: false,
isSuccess: false,
isError: false,
errorMessage: "",
}
export const signupUser = createAsyncThunk(
'users/signupUser',
//
//
// async ({ name, email, password} ... <<< This is the problem 1.
//
async ({ name, email, password }, thunkAPI) => {
try {
const response = await fetch(
'https://mock-user-auth-server.herokuapp.com/api/v1/users',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name,
email,
password,
}),
},
);
const data = await response.json();
console.log('data', data);
if (response.status === 200) {
localStorage.setItem('token', data.token);
return { ...data, username: name, email };
}
return thunkAPI.rejectWithValue(data);
} catch (e) {
console.log('Error', e.response.data);
return thunkAPI.rejectWithValue(e.response.data);
}
},
);
export const loginUser = createAsyncThunk(
'users/login',
async ({ email, password }, thunkAPI) => {
try {
const response = await fetch(
'https://mock-user-auth-server.herokuapp.com/api/v1/auth',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
}),
},
);
const data = await response.json();
console.log('response', data);
if (response.status === 200) {
localStorage.setItem('token', data.token);
return data;
}
return thunkAPI.rejectWithValue(data);
} catch (e) {
console.log('Error', e.response.data);
thunkAPI.rejectWithValue(e.response.data);
}
},
);
export const fetchUserBytoken = createAsyncThunk(
'users/fetchUserByToken',
async ({ token }, thunkAPI) => {
try {
const response = await fetch(
'https://mock-user-auth-server.herokuapp.com/api/v1/users',
{
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: token,
'Content-Type': 'application/json',
},
},
);
/* test case for Axios
const response = await axios.get(
'https://mock-user-auth-server.herokuapp.com/api/v1/users',
{
headers: {
Accept: 'application/json',
Authorization: token,
'Content-Type': 'application/json',
},
},
);
*/
const data = await response.json();
console.log('data', data, response.status);
if (response.status === 200) {
return { ...data };
}
return thunkAPI.rejectWithValue(data);
} catch (e) {
console.log('Error', e.response.data);
return thunkAPI.rejectWithValue(e.response.data);
}
},
);
export const userSlice = createSlice({
name: 'user',
initialState: {
username: '',
email: '',
isFetching: false,
isSuccess: false,
isError: false,
errorMessage: '',
},
reducers: {
clearState: state => {
state.isError = false;
state.isSuccess = false;
state.isFetching = false;
return state;
},
},
////
//// [signupUser.fulfilled] ... <<<< this is the problem 2.
////
////
extraReducers: {
[signupUser.fulfilled]: (state, { payload }) => {
console.log('payload', payload);
state.isFetching = false;
state.isSuccess = true;
state.email = payload.user.email;
state.username = payload.user.name;
},
[signupUser.pending]: state => {
state.isFetching = true;
},
[signupUser.rejected]: (state, { payload }) => {
state.isFetching = false;
state.isError = true;
state.errorMessage = payload.message;
},
[loginUser.fulfilled]: (state, { payload }) => {
state.email = payload.email;
state.username = payload.name;
state.isFetching = false;
state.isSuccess = true;
return state;
},
[loginUser.rejected]: (state, { payload }) => {
console.log('payload', payload);
state.isFetching = false;
state.isError = true;
state.errorMessage = payload.message;
},
[loginUser.pending]: state => {
state.isFetching = true;
},
[fetchUserBytoken.pending]: state => {
state.isFetching = true;
},
[fetchUserBytoken.fulfilled]: (state, { payload }) => {
state.isFetching = false;
state.isSuccess = true;
state.email = payload.email;
state.username = payload.name;
},
[fetchUserBytoken.rejected]: state => {
console.log('fetchUserBytoken');
state.isFetching = false;
state.isError = true;
},
},
});
export const { clearState } = userSlice.actions;
export const userSelector = (state: { user: UserState}) => state.user;
Upvotes: 1
Views: 245
Reputation: 44136
You'll need to define a type for the argument you put in there. If you only want to type the first argument and are fine with the defaults for thunkAPI
, you can use
export const signupUser = createAsyncThunk(
'users/signupUser',
async ({ name, email, password }: ArgumentType, thunkAPI) => {
Otherwise, you'll have to declare generic arguments as described in https://redux-toolkit.js.org/usage/usage-with-typescript#createasyncthunk
const fetchUserById = createAsyncThunk<
// Return type of the payload creator
MyData,
// First argument to the payload creator
number,
{
dispatch: AppDispatch
state: State
extra: {
jwt: string
}
}
>('users/fetchById', async (userId, thunkApi) => {
For problem #2 please see that we discourage the object map notation for extraReducers
as it is less typesafe in general and does not work in TypeScript. Please use the builder notation as described in https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation
Upvotes: 1