How to dispatch post data object using async thunk redux axios middleware - reactjs

I am trying to dispatch a post of an object data using async redux axios middleware. I am getting 400 https response prob due to formatting. Here is what I have for my code. Any feedback is great!
import { createAsyncThunk } from '#reduxjs/toolkit';
import axios from 'axios';
export const postResults = createAsyncThunk(
'results/postResults',
async ({ data: TestData[] }) => {
const response = await axios.post(`${url}/data/results`, { data });
return response.data;
}
);
const sendData = async (data) => {
try {
data = {
result: 'passed',
data_id: [0]
};
await dispatch(postResults(data));
} catch (err) {
console.log(err);
}
};
I am using sendData(data) in another function to trigger the event.
const processData = (e) => {
//.....
sendData(data);
}
The output I am getting when I debug under xhr.js request.send(requestData):
requestData: "{\"data\":{\"result\":\"passed\",\"data_id\":[0]}}"
I think the formatting is an issue which I have tried to remove data so I can be read and sent its request as
requestData: "{\"result\":\"passed\",\"data_id\":[0]}"
Any thoughts or feedback!

figured out, I removed the { } so its like this:
const response = await axios.post(${url}/data/results, data);

Related

React Query useQuery & Axios

I'm trying to create an API function with a help of React Query and Axios.
When I'm using useQuery with vanilla fetch function - it all works perfectly.
export const useGetDebts = async () => {
const { families } = appStore.user;
const res = useQuery("getDebts", async () => {
const res = await fetch(`${API_URL}/api/family/${families[0]}/debts`, {
method: "GET",
headers: {
Authorization: `Bearer ${appStore.token ?? ""}`,
},
});
const parsedBody: DebtsResponse = await res.json();
return parsedBody;
});
return res;
};
But when I switch the vanilla fetch function to Axios - I get an error status of 500 (not sure if it comes from React Query or Axios).
export const useGetDebts = async () => {
const { families } = appStore.user;
const res = useQuery("getDebts", async () => {
const res = await axiosInstance.get<DebtsResponse>(`/api/family/${families[0]}/debts`);
return res.data;
});
return res;
};
Thanks in advance for any explanations/suggestions.
P.s. The axiosInstance works fine with the useMutation hook. So it only makes me more confused. =(
export const useGetDebt = () => (
useMutation(async (id: number) => {
const { families } = appStore.user;
const res = await axiosInstance.get<DebtResponse>(`/api/family/${families[0]}/debts/${id}`);
return res.data;
})
);
P.s.s. I'm working with React Native if it's somehow relevant.
react-query doesn't give you any 500 errors because react-query doesn't do any data fetching. It just takes the promise returned from the queryFn and manages the async state for you.
I'm not sure if the fetch code really works because it doesn't handle any errors. fetch does not transform erroneous status codes like 4xx or 5xx to a failed promise like axios does. You need to check response.ok for that:
useQuery(['todos', todoId], async () => {
const response = await fetch('/todos/' + todoId)
if (!response.ok) {
throw new Error('Network response was not ok')
}
return response.json()
})
see Usage with fetch and other clients that do not throw by default.
So my best guess is that the fetch example also gives you a 500 error code, but you are not forwarding that error to react-query.

Calling an Existing Axios Function in another Function

I'm trying to call an existing function that makes an API request using axios in another function which also makes an API request but its unable to execute the function called. I'm relatively new to axios and react so I'm not sure if I'm missing something here and your help would be much appreciated. Also please note, I can call the API again via axios in the second function but instead of repeating the code I would rather like to do function call.
Function 1:
export const getUsers = () => async (dispatch) => {
try {
const resp = await axiosInstance.get("/api/users/");
dispatch({ type: GET_USERS, payload: resp.data });
} catch (error) {
dispatch(returnErrors(error.response.data, error.response.status));
}
}
Function 2:
export const deactivateUser = (userID) => async (dispatch) => {
try {
const res = await axiosInstance.put(`/api/user/disable/${userID}/`);
dispatch(createMessage({ deactivateUser: res.data }));
} catch (error) {
dispatch(returnErrors(error.response.data, error.response.status));
}
}
What I'm trying to achieve is following:
export const deactivateUser = (userID) => async (dispatch) => {
try {
const res = await axiosInstance.put(`/api/user/disable/${userID}/`);
dispatch(createMessage({ deactivateUser: res.data }));
getUsers(); // This is not getting called....
} catch (error) {
dispatch(returnErrors(error.response.data, error.response.status));
}
}
Any advice or help would be much appreciated!

Writing integration test for asynchronous code in React application with Context and useEffect

So, in useEffect I am fetching an object from the API then I am dispatching response data to the Context reducer and then updating the state. It looks something like this:
export const fetchItem = (id) => request({url: `/items/${id}`, method: 'get'});
...
const {dispatch, singleItem} = useProvider();
useEffect(() => {
const id = getItemIdFromUrl(props);
fetchItem(id).then((response) => {
dispatch(action(response.data.data));
});
}, [props, dispatch]);
I would like to write a good integration test for this. I am using react-testing-library with Jest. I am trying to mock the return value of the fetchItem function and then to check if everything is rendered correctly but constantly getting this warning:
act(() => {
/* fire events that update state */
});
/* assert on the output */
Any chance to do this correctly?
This is how the request method looks like:
import axios from 'axios';
import humps from 'humps';
import {getItem} from './localStorage';
const api = axios.create({
baseURL: process.env.REACT_APP_API_URL,
});
api.interceptors.response.use(
(response) => humps.camelizeKeys(response),
(error) => Promise.reject(error.response),
);
api.interceptors.request.use(
(request) => {
request.data = humps.decamelizeKeys(request.data);
return request;
},
(error) => Promise.reject(error.request),
);
export default function request({url, method, headers = {}, data}) {
try {
const token = getItem('token');
headers.Authorization = token;
return api({method, url, headers, data});
} catch (error) {
if (error.status === 500) {
console.log('HANDLE ERROR: ', error);
}
throw error;
}
}

Axios Error Networ error on request Google place api

im trying to make a request to google api but returns me network error. If i put the url in the browser, brings me the information correctly.I tryed to formate the request without success. The google places search works correctly too.
export const fetch_information = (skip, limit, filter) => async (dispatch) => {
try {
var url = `https://maps.googleapis.com/maps/api/place/details/json?place_id=ChIJk0aJYPbk3JQRLpKN20Jecko&fields=name,rating,formatted_phone_number&key=MyKey`;
const {data} = await axios.get(url)
console.log(data)
} catch (error) {
console.log(error.message)
}
}
and
export const fetch_information = (skip, limit, filter) => async (dispatch) => {
try {
var url = `https://maps.googleapis.com/maps/api/place/details/json?`;
let config = {
params: {
place_id: 'ChIJk0aJYPbk3JQRLpKN20Jecko',
key: 'myKey',
},
}
const {data} = await axios.get(url, config)
console.log(data)
} catch (error) {
console.log(error.message)
}
}
I think that the request looks a bit messy. I'm under the impression that you are trying to pass results to a redux store. Let's see if we can clean this up a bit.
export const fetch_information = async () => dispatch => {
const req = await axios.get("https://maps.googleapis.com/maps/api/place/details/json?place_id=ChIJk0aJYPbk3JQRLpKN20Jecko&fields=name,rating,formatted_phone_number&key=MyKey");
const data = await req.json();
return data;
//or, for your purpose...
console.log(data);
//can also dispatch for store
}
I didn't see anything you were passing as necessary for this.

How to implement redux thunk actions with offline functionality?

For a project i need to implement some kind of offline redux-action queue.
And i'm using redux-thunk for async actions. But i saw that libraries like redux-offline can't handle async actions with redux thunk yet.
Does anyone have an idea how i can best tackle this?
My actions look like this:
export function fetchIdeasForOrganisationAction(organisation) {
const options = {
credentials: 'include',
};
return async (dispatch) => {
try {
const response = await fetch(`http://${SERVER_URL}:${SERVER_PORT}/organisations/${organisation}/shared/ideas`, options);
if (!response.ok) throw Error();
const ideas = await response.json();
dispatch(newIdeasFetched(ideas));
} catch (e) {
dispatch(noIdeasFoundAction('No ideas found '));
}
};
}
function newIdeasFetched(ideas) {
return { type: "NEW_IDEAS_FETCHED", value: ideas };
}
function noIdeasFoundAction(errorMessage) {
return { type: 'NO_IDEAS_FOUND', errorMessage };
}

Resources