I try to work with Axios interceptors. The problem I'm facing is that I can't show the response I got from the API with Axios or even if it does, it shows constant data.
axios.defaults.baseURL = 'https://localhost:5001/api/';
axios.defaults.withCredentials = true;
const responseBody = res => res.data;
axios.interceptors.response.use(async response => {
const pagination = response.headers["x-pagination"];
if (pagination) {
const parsed = JSON.parse(pagination);
let metaData = {
currentPage: parsed.currentPage,
pageSize: parsed.pageSize,
totalPages: parsed.totalPages,
totalCount: parsed.totalCount
};
response.data = {
metaData,
data: response.data //I want to change this data
// For example there is an endpoint named getAll and it returns all object
// Also there is a get endpoint and it returns a single object
// But the problem is axios always return getAll endpoint's data.
};
return response;
}
}, error => {
return Promise.reject(error);
});
This is my request object
const requests = {
get: (url, params) => axios.get(url, {params}).then(responseBody),
post: (url, data) => axios.post(url, data).then(responseBody),
put: (url, data) => axios.put(url, data).then(responseBody),
delete: (url) => axios.delete(url).then(responseBody),
postForm: (url, data) => axios.post(url, data, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(responseBody),
putForm: (url, data) => axios.put(url, data, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(responseBody)
};
and this is my API endpoints
const Endpoints = {
getAll: () => requests.get('Endpoint'),
get: (id) => requests.get(`Endpoint/${id}`),
create: (data) => requests.postForm('Endpoint', data),
update: (id, data) => requests.putForm(`Endpoint/${id}`, data),
delete: (id) => requests.delete(`Endpoint/${id}`),
}
What am I missing? Also, I use Redux Slice. If you want I can also send the redux code I write.
axios.interceptors.response.use(async response => {
const pagination = response.headers["x-pagination"];
if (pagination) {
const parsed = JSON.parse(pagination);
let metaData = {
currentPage: parsed.currentPage,
pageSize: parsed.pageSize,
totalPages: parsed.totalPages,
totalCount: parsed.totalCount
};
response.data = {
metaData,
data: response.data
};
return response;
}
return response; // problem solved after this
}, error => {
return Promise.reject(error);
});
The problem is I forget to return the response so that's why I always get the same data.
Related
i am using Redux-Toolkit-Query in Reactjs Project, I have Number of end points. For Each Endpoint i have to add one common parameter with body , i tried below snippet on QueryStarted adding that Language parameter, but i am repeating this code for each enpoint and sometimes its not working.
updatePassword: builder.mutation({
query: (body) => ({
url: URL.UPDATE_PASSWORD,
method: "POST",
body: body,
responseHandler: (response) => response.json(),
validateStatus: (response, result) =>
response.status === 200 && result.success === 1,
}),
transformResponse: (response) => {
return response;
},
async onQueryStarted(body, { dispatch, queryFulfilled, getState }) {
const language = await UTILS?.asyncLocalStorage.getLanguage(); //Here How to add this with body
body.language = language;
const { history } = body;
try {
dispatch(LoaderAction.setLoading(true));
const { data } = await queryFulfilled;
if (data) {
UTILS.handleSuccesNotification(
data?.message ?? "Password updated sucessfully"
);
history.goBack();
}
} catch (err) {}
dispatch(LoaderAction.setLoading(false));
},
}),
I have an apiClient file which contains the generic get method below
export const API_URL = 'https://localhost:40000';
const query = async <T>(request: RequestInfo, options?: RequestInit): Promise<T> => {
return fetch(request, options).then(response => {
if (!response.ok) {
throw response;
}
return response.json();
});
};
export const get = async <T>(url: string): Promise<T> =>
query(`${API_URL}${url}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
mode: 'cors',
cache: 'default'
});
In my services, I have a function that calls the get method (fetch) and takes a string URL.
const getAllProjects = async () => {
try {
const response = await get<Response>('/Projects');
if (response.ok) {
const jsonData = await response.json();
const projects = await jsonData.data;
return projects;
}
console.log(response);
} catch (error) {
console.log(error);
}
};
However, the issue I am facing is when I call the query method in the generic get method, it returns [object Object]. I have tried to pass in a string URL and replace it with ${API_URL}${url} but this also returned the same outcome.
network.services.js
axiosCall = (axiosURL) => {
// const axiosURL = "https://api.github.com/user"
axios.get(axiosURL, {
headers: {
'Authorization': `qwdvryjutmnevw`,
}
}).then((res) => {
console.log(res.data);
return res.data;
}).catch((error) => {
throw error.message;
// console.error(error);
// toast.error(error.message);
})
}
component.js
const getData = async () => {
const asyncExample = async () => {
const result = await networkServices.axiosCall("/api/v1/calendars");
const responseData = await result;
console.log(responseData);
return responseData;
}
const data = asyncExample()
data.then(function(result) {
console.log(result); // "Some User token"
})
}
Trying to get data from service to my component in const result, console form service is consoling data but component is always returning undefined instead of data from the service file. SetTimeout function is also not working in component.
You have many mistakes. I advise you to take a look at documentation about Promises
First one:
You don't return data in axiosCall
A way to return data:
axiosCall = (axiosURL) => new Promise((resolve, reject) => {
axios.get(axiosURL, {
headers: {
'Authorization': `yourTokenHere`,
}
}).then((res) => {
// return a response data
resolve(res.data);
}).catch((error) => {
// return only error message
reject(error.message);
})
})
to use axiosCall:
try {
// don't forgot to configure axios with base url
const data = await axiosCall('/api/v1/calendars');
// do something with your data
} catch (e) {
// do something with error message
console.log(e);
}
Second:
Your make mistakes when call async function
Look at this example:
const getData = () => {
networkServices
.axiosCall("/api/v1/calendars")
.then(function(result) {
// when promise resolve
console.log(result);
})
.catch(error => {
// when promise reject
console.log(error)
})
}
My backend API route is /api/updateUser/:id
How am I supposed to POST data into this API? I'm familiar with POST request for non params APIs but this one has an /:id in the route.
Can someone show me an example with this demo code
state = {
username: "random123",
password: "random123",
userid: "qwertyuiop",
};
saveDetails = async () => {
const { username, password, userid } = this.state;
let data = new FormData();
data.append('username',username);
data.append('password',password);
axios
.put(apiEndPoint+'?id='+this.state.userid, data) //this is where I need help
.then(async (response) => {
if (response.data) {
console.log("success");
} else {
console.log("issue");
}
})
.catch((err) => {
console.log("error",err);
});
};
This is the working example for Path Parameter Axios PUT request -
saveDetails = async () => {
const { username, password, userid } = this.state;
axios
.put(apiEndPoint+"updateUser/"+userid, {
username:username,
password:password,
})
.then(async (response) => {
if (response.data) {
console.log("done");
} else {
console.log("error");
}
})
.catch((err) => {
console.log("error",err);
});
};
I am trying to call 3rd party API, to fetch some data. I am getting the response in Postman, but not getting expected response when I execute my code.
I tried in 2 ways. Both ways I am getting "Promise pending".What could be the reason??
//request.js
Method 1
export const callSearchGiftsAPI = inputs => dispatch => {
dispatch(searchGifts());
let url = new URL(GIFT_SEARCH_API_URL),
params = {
apiKey: GIFT_SEARCH_API_KEY,
query: inputs.item,
country: 'us',
itemsPerPage: 3
};
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
return new Promise((resolve, reject) => {
setTimeout(() => resolve(
fetch(url, {
method: 'GET',
// mode: 'no-cors',
headers: {
'Content-Type': 'application/json',
Authorization: `secret ${SECRET}`
}
})
.then(res => {
if (!res.ok) {
return Promise.reject(res.statusText);
}
console.log("hi", res.json());
return res.json();
})
.then(gifts => dispatch(searchGiftsSuccess(gifts)))
.catch(err => dispatch(searchGiftsError(err)))), 500)
});
}
Method 2:
export const callSearchGiftsAPI = inputs => dispatch => {
dispatch(searchGifts());
let url = new URL(GIFT_SEARCH_API_URL),
params = {
apiKey: GIFT_SEARCH_API_KEY,
query: inputs.item,
country: 'us',
itemsPerPage: 3
};
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
fetch(url, {
method: 'GET',
// mode: 'no-cors',
headers: {
'Content-Type': 'application/json',
Authorization: `secret ${SECRET}`
}
})
.then(res => {
if (!res.ok) {
return Promise.reject(res.statusText);
}
console.log('result', res.json());
return res.json();
})
.then(gifts => dispatch(searchGiftsSuccess(gifts)))
.catch(err => dispatch(searchGiftsError(err)));
};
//form.js
class Form extend React.Component{
onSubmit(values) {
const inputs = Object.assign({}, values);
return this.props.dispatch(callSearchGiftsAPI(inputs));
}
//Remaining code
}
Also please note that I have installed CORS plugin in Chrome, to allow the request.If I disable it and add mode:'no-cors' I am getting as 401 unauthorized.What else am I supposed to do?
What happens is that you are creating a new Promise and returning it, but you are not waiting for it to resolve. You can either use then of the new async/await syntax to get the correct result :
onSubmit = async values => {
const inputs = Object.assign({}, values);
return await this.props.dispatch(callSearchGiftsAPI(inputs));
}
The code above will work with your first method.
Since your second method does not return anything, you will never get your result, you need to return your fetch's result and apply the code I gave above :
return fetch(url, {
This worked.
I was trying to put console.log in the wrong place and hence was not able to see the response properly.
export const callSearchGiftsAPI = inputs => dispatch => {
dispatch(searchGifts());
let url = new URL(GIFT_SEARCH_API_URL),
params = {
apiKey: GIFT_SEARCH_API_KEY,
query: inputs.item,
country: 'us',
itemsPerPage: 3
};
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
console.log(url);
return fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `secret ${SECRET}`
}
})
.then(res => {
console.log('result');
return res.json();
})
.then(response => {
console.log(response); // changed
dispatch(searchGiftsSuccess(response.items));
})
.catch(err => dispatch(searchGiftsError(err)));