mockResolvedValueOnce works with await but mockRejectedValueOnce doesn't - javascript

I am working on my test for a new project and have them set up but am running into an async issue with jest.
I start with jest.mock('axios');
And the working test is
it('Dispatches SNACK_BAR after submitting ForgotPassword', async () => {
let store = configureStore({ reducer: {
auth: authReducer,
snackBar: snackBarReducer
}})
axios.post.mockResolvedValueOnce({headers: {
authorization: 'asdasdasdas'
},
status: 200});
await store.dispatch(forgotPasswordActions.forgotPasswordPost('test#test.com', (path) => {}))
expect(store.getState().snackBar).toEqual({"message": "Check your email for a reset link", "severity": "success", "timestamp": store.getState().snackBar.timestamp});
});
But when I try the fail case
it('Dispatches SNACK_BAR after submitting ForgotPassword with an error', async () => {
let store = configureStore({ reducer: {
auth: authReducer,
snackBar: snackBarReducer
}})
axios.post.mockRejectedValueOnce({response: {headers: {
authorization: 'asdasdasdas'
},
status: 500,
data: {
error: 'Error'
}}});
await store.dispatch(forgotPasswordActions.forgotPasswordPost('test#test.com', (path) => {}))
expect(store.getState().snackBar).toEqual({"message": "Error", "severity": "error"});
})
The expect doesn't wait for the dispatch to resolve. If I change the mockRejectedValueOnce to mockResolvedValueOnce then I get a similar result to the first test. It seems the only difference is mockRejectedValueOnce but I am not sure why
export const forgotPasswordPost = ({ email }, navigate) => async dispatch => {
axios.post(`${ROOT_URL}/auth/password`,
{ "user": { email: email }})
.then(response => {
return dispatch({ type: SNACK_BAR, payload: ["Check your email for a reset link", "success"]})
})
.catch(response => {
return dispatch({ type: SNACK_BAR, payload: ["Error", "error"]});
})
}
The function that is being tested

In forgotPasswordPost you return async function async dispatch => {}. This function has to return a promise. But currently it is void
/// original function
export const forgotPasswordPost = ({ email }, navigate) => async dispatch => {
axios.post(`${ROOT_URL}/auth/password`,
{ "user": { email: email }})
.then(response => {
return dispatch({ type: SNACK_BAR, payload: ["Check your email for a reset link", "success"]})
})
.catch(response => {
return dispatch({ type: SNACK_BAR, payload: ["Error", "error"]});
})
}
/// Try to to return THE Promise, not you return the axios.post promise chain
export const forgotPasswordPost = ({ email }, navigate) => async dispatch => {
return axios.post(`${ROOT_URL}/auth/password`,
{ "user": { email: email }})
.then(response => {
return dispatch({ type: SNACK_BAR, payload: ["Check your email for a reset link", "success"]})
})
.catch(response => {
return dispatch({ type: SNACK_BAR, payload: ["Error", "error"]});
})
}
/// ANother proposal using async await
export const forgotPasswordPost = ({ email }, navigate) => async dispatch => {
try {
const response = await axios.post(`${ROOT_URL}/auth/password`, { "user": { email: email }});
dispatch({ type: SNACK_BAR, payload: ["Check your email for a reset link", "success"]})
} catch (e) {
dispatch({ type: SNACK_BAR, payload: ["Error", "error"]});
}
}

Related

Warn : Possible Unhandled Promise Rejection (id: 0)

I am building ecommerce app using react-native I just encountered an error which i don't know what it mean
Error is "Possible Unhandled Promise Rejection (id: 0):
TypeError: undefined is not an object (evaluating 'err.response.data')"
I have used "err.response.data" in 2-3 file but i have mentioned code of one file
import AsyncStorage from '#react-native-community/async-storage';
import axios from 'axios';
import {returnErrors} from './errorActions';
import {ADD_TO_CART, CHECK_OUT} from './types';
import {
AllDispatchProp,
API_URI,
CLEAR_ERRORS,
DELETE_PRODUCT,
LOADED_PRODUCTS,
LOADING_PRODUCTS,
SENT_PRODUCT,
} from './types';
export const addProduct = ({
title,
price,
imageUrl,
desc,
}: {
title: string;
price: string;
imageUrl: string;
desc: string;
}) => async (dispatch: AllDispatchProp, getState: any) => {
const auth = getState().auth;
const data = JSON.stringify({title, price, imageUrl, desc, user: auth.user});
const token = AsyncStorage.getItem('#user_token');
//* Store a product
axios({
method: 'POST',
url: `${API_URI}/api/product`,
data,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: CLEAR_ERRORS, payload: null});
dispatch({type: SENT_PRODUCT, payload: res.data._doc});
})
.catch((err) => {
dispatch(
returnErrors(
err.response.data,
err.response.status,
'PRODUCT_POST_FAIL',
),
);
});
};
//* Load Amazon Products *//
export const loadProducts = () => async (dispatch: AllDispatchProp) => {
dispatch({type: LOADING_PRODUCTS, payload: null});
const token = await AsyncStorage.getItem('#user_token');
//* Load products from url *//
axios({
method: 'GET',
url: `${API_URI}/api/product`,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: LOADED_PRODUCTS, payload: res.data});
})
.catch((err) => {
dispatch(
returnErrors(
err.response.data,
err.response.status,
'LOAD_PRODUCT_FAIL',
),
);
});
};
export const deleteProduct = (_id: string) => async (
dispatch: AllDispatchProp,
) => {
const data = JSON.stringify({_id});
const token = await AsyncStorage.getItem('#user_token');
axios({
method: 'DELETE',
url: `${API_URI}/api/product`,
data,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: DELETE_PRODUCT, payload: res.data._id});
})
.catch((err) => {
dispatch(
returnErrors(
err.response.data,
err.response.status,
'DELETE_PRODUCT_FAIL',
),
);
});
};
//* Amazon add to cart *//
export const addToCart = (_id: string) => async (
dispatch: AllDispatchProp,
getState: any,
) => {
const {products, cartProducts} = getState().product;
const cartProduct = cartProducts.filter((p: any) => p._id === _id);
const isInCart = cartProduct.length > 0;
const data = JSON.stringify({_id});
const token = await AsyncStorage.getItem('#user_token');
if (!isInCart) {
axios({
method: 'PUT',
url: `${API_URI}/api/product`,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
data,
})
.then((res) => {
dispatch({type: ADD_TO_CART, payload: res.data});
})
.catch((err) => {
dispatch(
returnErrors(
err.response.data,
err.response.status,
'ADD_TO_CART_FAIL',
),
);
});
}
};
export const productCheckOut = () => async (dispatch: AllDispatchProp) => {
const token = await AsyncStorage.getItem('#user_token');
axios({
method: 'GET',
url: `${API_URI}/api/product`,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: CHECK_OUT, payload: res.data});
})
.catch((err) => {
dispatch(
returnErrors(err.response.data, err.response.status, 'CHECKOUT_FAIL'),
);
});
};
export const clearCart = () => async (dispatch: AllDispatchProp) => {
const token = await AsyncStorage.getItem('#user_token');
axios({
method: 'PUT',
url: `${API_URI}/api/product/clear`,
headers: {
'x-app-token': token,
},
})
.then(() => {
return loadProducts();
})
.catch(() => {});
};
I dont from where this error occurred but I really need help in this on
This is the "returnErrors" file
import {GET_ERRORS, CLEAR_ERRORS} from './types';
// RETURN ERRORS
export const returnErrors = (
msg: string,
status: string | number,
id: string | null,
) => {
return {
type: GET_ERRORS,
payload: {msg, status, id},
};
};
// CLEAR ERRORS
export const clearErrors = () => {
return {
type: CLEAR_ERRORS,
};
};
After editing;
import AsyncStorage from '#react-native-community/async-storage';
import axios from 'axios';
import {returnErrors} from './dist/errorActions';
import {ADD_TO_CART, CHECK_OUT} from './dist/types';
import {
AllDispatchProp,
API_URI,
CLEAR_ERRORS,
DELETE_PRODUCT,
LOADED_PRODUCTS,
LOADING_PRODUCTS,
SENT_PRODUCT,
} from './types';
export const addProduct = ({
title,
price,
imageUrl,
desc,
}: {
title: string;
price: string;
imageUrl: string;
desc: string;
}) => async (dispatch: AllDispatchProp, getState: any) => {
const auth = getState().auth;
const data = JSON.stringify({title, price, imageUrl, desc, user: auth.user});
const token = AsyncStorage.getItem('#user_token');
//* Store a product
axios({
method: 'POST',
url: `${API_URI}/api/product`,
data,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: CLEAR_ERRORS, payload: null});
dispatch({type: SENT_PRODUCT, payload: res.data._doc});
})
.catch((err) => {
dispatch(
returnErrors(
err.response?.data ?? 'your default msg',
err.response?.status ?? 'your default status',
'PRODUCT_POST_FAIL',
),
);
});
};
//* Load app Products *//
export const loadProducts = () => async (dispatch: AllDispatchProp) => {
dispatch({type: LOADING_PRODUCTS, payload: null});
const token = await AsyncStorage.getItem('#user_token');
//* Load products from url *//
axios({
method: 'GET',
url: `${API_URI}/api/product`,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: LOADED_PRODUCTS, payload: res.data});
})
.catch((err) => {
dispatch(
returnErrors(
err.response.data,
err.response.status,
'LOAD_PRODUCT_FAIL',
),
);
});
};
export const deleteProduct = (_id: string) => async (
dispatch: AllDispatchProp,
) => {
const data = JSON.stringify({_id});
const token = await AsyncStorage.getItem('#user_token');
axios({
method: 'DELETE',
url: `${API_URI}/api/product`,
data,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: DELETE_PRODUCT, payload: res.data._id});
})
.catch((err) => {
dispatch(
returnErrors(
err.response.data,
err.response.status,
'DELETE_PRODUCT_FAIL',
),
);
});
};
//* app add to cart *//
export const addToCart = (_id: string) => async (
dispatch: AllDispatchProp,
getState: any,
) => {
const {products, cartProducts} = getState().product;
const cartProduct = cartProducts.filter((p: any) => p._id === _id);
const isInCart = cartProduct.length > 0;
const data = JSON.stringify({_id});
const token = await AsyncStorage.getItem('#user_token');
if (!isInCart) {
axios({
method: 'PUT',
url: `${API_URI}/api/product`,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
data,
})
.then((res) => {
dispatch({type: ADD_TO_CART, payload: res.data});
})
.catch((err) => {
dispatch(
returnErrors(
err.response.data,
err.response.status,
'ADD_TO_CART_FAIL',
),
);
});
}
};
export const productCheckOut = () => async (dispatch: AllDispatchProp) => {
const token = await AsyncStorage.getItem('#user_token');
axios({
method: 'GET',
url: `${API_URI}/api/product`,
headers: {
'content-type': 'application/json',
'x-app-token': token,
},
})
.then((res) => {
dispatch({type: CHECK_OUT, payload: res.data});
})
.catch((err) => {
dispatch(
returnErrors(err.response.data, err.response.status, 'CHECKOUT_FAIL'),
);
});
};
export const clearCart = () => async (dispatch: AllDispatchProp) => {
const token = await AsyncStorage.getItem('#user_token');
axios({
method: 'PUT',
url: `${API_URI}/api/product/clear`,
headers: {
'x-app-token': token,
},
})
.then(() => {
return loadProducts();
})
.catch(() => {});
};
and returnErrors file
Note: when i am editing returnError code i got an error "Unexpected Token" on question mark symbol
import {GET_ERRORS, CLEAR_ERRORS} from './types';
// RETURN ERRORS
export const returnErrors = (
msg: string | undefined,
status: string | number | undefined,
id: string | null,
) => {
return {
type: GET_ERRORS,
payload: {msg??"your default msg", status??"your default status", id},
};
};
// CLEAR ERRORS
export const clearErrors = () => {
return {
type: CLEAR_ERRORS,
};
};
One more thing whenever i'm trying to register in app it throw this error only(i hope u understand what i'm trying to say)
Maybe you can check if the params for returnErrors() exist before passing them
.catch((err) => {
dispatch(
returnErrors(
err.response?.data ?? "your default msg",
err.response?.status ?? "your default status",
'PRODUCT_POST_FAIL',
),
);
});
or you can teach your returnErrors function how to deal with undefined params
export const returnErrors = (
msg: string | undefined,
status: string | number | undefined,
id: string | null,
) => {
return {
type: GET_ERRORS,
payload: {msg:msg??"your default msg", status:status??"your default status", id},
};
};
You would have to provide the signature of the returnErrors function for a better analysis but I think this function expects an object as its first argument while err.response.data could be undefined. That would throw a type error in an asynchronous part of the code, resulting in the Unhandled Promise Rejection.
To resolve this, you could check the kind of data you send to returnErrors every time you call it, or make the function returnErrors receive any kind of data and format it accordingly. I would rather implement the latter.

How to test a recursive dispatch in Redux

I implemented my own way to handle access/refresh token. Basically when accessToken is expired, it awaits the dispatch of another action and, if it is successful, it dispatch again itself. The code below explains it better:
export const refresh = () => async (dispatch) => {
dispatch({
type: REFRESH_USER_FETCHING,
});
try {
const user = await api.refresh();
dispatch({
type: REFRESH_USER_SUCCESS,
payload: user,
});
return history.push("/");
} catch (err) {
const { code } = err;
if (code !== "ACCESS_TOKEN_EXPIRED") {
dispatch({
type: REFRESH_USER_ERROR,
payload: err,
});
const pathsToRedirect = ["/signup"];
const {
location: { pathname },
} = history;
const path = pathsToRedirect.includes(pathname) ? pathname : "/login";
return history.push(path);
}
try {
await dispatch(refreshToken());
return dispatch(refresh());
} catch (subErr) {
dispatch({
type: REFRESH_USER_ERROR,
payload: err,
});
return history.push("/login");
}
}
};
export const refreshToken = () => async (dispatch) => {
dispatch({
type: REFRESH_TOKEN_FETCHING,
});
try {
await api.refreshToken();
dispatch({
type: REFRESH_TOKEN_SUCCESS,
});
} catch (err) {
dispatch({
type: REFRESH_TOKEN_ERROR,
payload: err,
});
}
};
the issue is that I am finding it really difficult to test with Jest. In fact, I have implemented this test:
import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";
import * as actionCreators from "./actionCreators";
import * as actions from "./actions";
import api from "../../api";
jest.mock("../../api");
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
describe("authentication actionCreators", () => {
it("runs refresh, both token expired, should match the whole flow", async () => {
api.refresh.mockRejectedValue({
code: "ACCESS_TOKEN_EXPIRED",
message: "jwt expired",
});
api.refreshToken.mockRejectedValue({
code: "REFRESH_TOKEN_EXPIRED",
message: "jwt expired",
});
const expectedActions = [
{ type: actions.REFRESH_USER_FETCHING },
{ type: actions.REFRESH_TOKEN_FETCHING },
{ type: actions.REFRESH_TOKEN_ERROR },
{ type: actions.REFRESH_USER_ERROR },
];
const store = mockStore({ auth: {} });
await store.dispatch(actionCreators.refresh());
expect(store.getActions()).toEqual(expectedActions);
});
});
but instead of completing, the test runs indefenitely. This issue is not happening when I am testing it manually, so I think there is something missing in Jest, so my question is: is there a way to test this recursive behaviour?
Thanks
The problem is await you use with dispatch, dispatch returns an action, not a Promise, use Promise.resolve instead.

How to catch error seperate for two await within one try catch

I have a function with two await promises runing in one try catch block in Redux actions. I was only catching the error for adding new project. If I want to catch the error from participant add, how should I do? The add participant function only run if a new project is created and once it successes, the participant can get the new created project ID, that's why I put these two await together.
const handleProjectParticipant = async (project, participant) => async (dispatch) => {
try {
const resultProject = await createNewProject(project)
dispatch({ type: PROJECT_ADD, payload: resultProject })
const newProject_id = resultProject.id
participant.project_id = newProject_id
const resultParticipant = await addParticipant(participant)
dispatch({ type: PARTICIPANT_ADD, payload: resultParticipant })
}
catch(e) {
dispatch({ type: PROJECT_ADD_FAIL, payload: e})
//want to catch error for add participant
//dispatch({ type: PARTICIPANT_ADD_FAIL, payload: e})
}
}
You can nest another try/catch in the first:
const handleProjectParticipant = async (project, participant) => async (dispatch) => {
try {
const resultProject = await createNewProject(project)
dispatch({ type: PROJECT_ADD, payload: resultProject })
const newProject_id = resultProject.id
participant.project_id = newProject_id
try {
const resultParticipant = await addParticipant(participant)
dispatch({ type: PARTICIPANT_ADD, payload: resultParticipant })
} catch(e) {
dispatch({ type: PARTICIPANT_ADD_FAIL, payload: e})
}
}
catch(e) {
dispatch({ type: PROJECT_ADD_FAIL, payload: e})
}
}
Or you could just do something like:
const handleProjectParticipant = async (project, participant) => async (dispatch) => {
let handleError = (e) => dispatch({ type: PROJECT_ADD_FAIL, payload: e})
try {
const resultProject = await createNewProject(project)
dispatch({ type: PROJECT_ADD, payload: resultProject })
const newProject_id = resultProject.id
participant.project_id = newProject_id
handleError = (e) => dispatch({ type: PARTICIPANT_ADD_FAIL, payload: e})
const resultParticipant = await addParticipant(participant)
dispatch({ type: PARTICIPANT_ADD, payload: resultParticipant })
}
catch(e) {
handleError(e)
}
}

Re-Authenticate User after Email Change Firebase React

I have built a feature that allows a logged in User to update their email. When I change the email and redirect to a different page the email that is displayed is the old email, and only when I refresh the page does the new email appear. I believe the the best way to address this is for the system to re-authenticate the User (I may be wrong and am open to suggestions).
// UpdateEmail.js
handleSubmit(e) {
e.preventDefault()
this.props.updateEmail(this.state.newEmail)
this.props.history.push('/settings')
}
const mapDispatchToProps = (dispatch) => {
return {
updateEmail: (newEmail) => dispatch(updateEmail(newEmail))
}
}
// authActions.js *NEW*
export const updateEmail = (newEmail, oldEmail, password) => {
return (dispatch, getState, {getFirebase, getFirestore}) => {
const firebase = getFirebase();
let user = firebase.auth().currentUser
let credential = firebase.auth.EmailAuthProvider.credential(oldEmail, password);
user.reauthenticateAndRetrieveDataWithCredential(credential)
.then(() => {
user.updateEmail(
newEmail
).then(() => {
dispatch({ type: 'UPDATE_LOGIN_DETAILS_SUCCESS'})
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
dispatch({
type: 'CHECK_REAUTH_SUCCESS',
user: user
})
} else {
dispatch({ type: 'CHECK_REAUTH_ERROR'})
}
});
})
.catch(err => {
dispatch({ type: 'UPDATE_LOGIN_DETAILS_ERROR'}, err)
})
})
.catch(err => {
dispatch({ type: 'REAUTH_ERROR'}, err)
})
}
}
// Settings.js this is where the user is redirected after CHECK_REAUTH_SUCCESS
const mapStateToProps = (state) => {
return {
licenses: state.firestore.ordered.licenses,
aircraft: state.firestore.ordered.aircraft,
profile: state.firebase.profile,
auth: state.firebase.auth
}
}
// authActions.js *OLD*
export const updateEmail = (newEmail) => {
return (dispatch, getState, {getFirebase, getFirestore}) => {
const firebase = getFirebase();
const user = firebase.auth().currentUser
user.updateEmail(
newEmail
).then(() => {
dispatch({ type: 'UPDATE_LOGIN_EMAIL_SUCCESS'})
}).catch(err => {
dispatch({ type: 'UPDATE_LOGIN_EMAIL_ERROR', err })
})
}
}

ReactJS: How to implement react-cookie properly in an action?

I have read articles that saving the token in localstorage is dangerous to XSS attack. So I have decided to store my tokens in cookies. And I am using react-cookie. I saw the examples and I am trying to do it but my auth.js consists of const and is not a class, so I do not know how to use the withCookies() with it, this is my auth.js where I want to store the token to the cookies:
import {
LOGIN,
LOGIN_SUCCESS,
LOGIN_FAILED,
GET_USER_DATA,
GET_USER_DATA_SUCCESS,
GET_USER_DATA_FAILED,
LOGOUT,
LOGOUT_SUCCESS,
LOGOUT_FAILED,
} from './types'
import axios from 'axios'
var api = require ('./../api.js');
export const login = (email, pass) => {
return (dispatch) => {
dispatch({
type: LOGIN
})
var url = api.logInApi
axios.post(url, {
email: email,
password: pass
})
.then(res => {
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
})
localStorage.setItem('token', res.data.token)
dispatch(getUserData())
})
.catch(err => dispatch({
type: LOGIN_FAILED,
payload: err
}))
}
}
export const getUserData = () => {
return (dispatch) => {
dispatch({
type: GET_USER_DATA
})
var url = api.getUserDataApi
axios.post(url, {}, {headers: {
"Authorization": `Bearer ${localStorage.getItem("token")}`
}})
.then(res => {
dispatch({
type: GET_USER_DATA_SUCCESS,
payload: res.data
})
})
.catch(err => dispatch({
type: GET_USER_DATA_FAILED,
payload: err
}))
}
}
export const logout = () => {
return (dispatch) => {
dispatch({
type: LOGOUT
})
var url = api.logoutApi
axios.post(url, {}, {headers: {
"Authorization": `Bearer ${localStorage.getItem("token")}`
}})
.then(res => {
window.location.replace("")
dispatch({
type: LOGOUT_SUCCESS,
payload: res.data
})
})
.catch(err => dispatch({
type: LOGOUT_FAILED,
payload: err
}))
}
}
Now, I tried doing this and of course it doesn't work:
import {
LOGIN,
LOGIN_SUCCESS,
LOGIN_FAILED,
GET_USER_DATA,
GET_USER_DATA_SUCCESS,
GET_USER_DATA_FAILED,
LOGOUT,
LOGOUT_SUCCESS,
LOGOUT_FAILED,
} from './types'
import axios from 'axios'
import { withCookies, Cookies } from 'react-cookie'; <<added this
var api = require ('./../api.js');
const login = (email, pass) => {
return (dispatch) => {
dispatch({
type: LOGIN
})
const { cookies } = props; <<added this
var url = api.logInApi
axios.post(url, {
email: email,
password: pass
})
.then(res => {
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
})
cookies.set('token', res.data.token, { path: '/' }); <<added this
dispatch(getUserData())
})
.catch(err => dispatch({
type: LOGIN_FAILED,
payload: err
}))
}
}
export default withCookies(login) <<added this(wrong)
const getUserData = () => {
return (dispatch) => {
dispatch({
type: GET_USER_DATA
})
const { cookies } = props; <<added this
var token = cookies.get('token'); <<added this
var url = api.getUserDataApi
axios.post(url, {}, {headers: {
"Authorization": `Bearer ${token}` <<added this(this is where I wanna get the cookie)
}})
.then(res => {
dispatch({
type: GET_USER_DATA_SUCCESS,
payload: res.data
})
})
.catch(err => dispatch({
type: GET_USER_DATA_FAILED,
payload: err
}))
}
}
export default withCookies(getUserData) <<added this(wrong)
const logout = () => {
return (dispatch) => {
dispatch({
type: LOGOUT
})
const { cookies } = props;
var token = cookies.get('token');
var url = api.logoutApi
axios.post(url, {}, {headers: {
"Authorization": `Bearer ${token}` <<added this
}})
.then(res => {
window.location.replace("")
dispatch({
type: LOGOUT_SUCCESS,
payload: res.data
})
})
.catch(err => dispatch({
type: LOGOUT_FAILED,
payload: err
}))
}
}
export default withCookies(logout) <<added this(wrong)
this one is wrong because there should only be one export default. But I don't know how to implement withCookies to const and there are also these ones that are included in the example and I don't know if I need them or where do I put them:
static propTypes = {
cookies: instanceOf(Cookies).isRequired
};
constructor(props) {
super(props);
const { cookies } = props;
this.state = {
name: cookies.get('name') || 'Ben'
};
}
and also, another question is that, I can access my cookies anywhere in my project right? just like how localstorage is accessible to my project?
I hope someone can help me and I am a newbie to this. I have never used cookies before so thank you for your consideration.
I personally would rather using js-cookie to write/read cookies.
It has a very basic API:
Cookie.set('cookie_name', 'value') // will set "cookie_name" to "value"
Cookie.get('cookie_name') // will return "value"
Which means:
const login = (email, pass, cookie) => {
return (dispatch) => {
dispatch({
type: LOGIN
})
var url = api.logInApi
axios.post(url, {
email: email,
password: pass
})
.then(res => {
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
})
cookies.set('token', res.data.token);
dispatch(getUserData())
})
.catch(err => dispatch({
type: LOGIN_FAILED,
payload: err
}))
}
}
Passing to the login funuction js-cookie's Cookie in the 3rd argument.
Now, you can still use the same react-cookie package to read the cookie values (I believe there shouldn't be any conflicts). Or you can replace it with js-cookie. To do that, however, you will have to pass the Cookie object to props. I probably would do that using mapStateToProps if you're using Redux or just by simply passing it through JSX

Categories