ApiClient - fetch returns [object Object] - reactjs

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.

Related

I want to save the axios.post request in a const and return that const in the function

export async function getCategories() {
const https = "xxxxxx";
const url = `${https}/api/Category/GetCategories`;
const userToken ="xxxxxxxx"
const authStr = "Bearer ".concat(userToken);
const options = {
method: "POST",
headers: {
Authorization: authStr,
},
url: url,
};
const response = await axios(options)
.then((response) => console.log(response.data[0].categoryName))
.catch((error) => console.log(error.toJSON()));
const fetchedCategories = response.data[0];
console.log(
"🚀 ~ file: menu.js:27 ~ getCategories ~ fetchedCategories",
fetchedCategories
);
return fetchedCategories;
when I
console.log(response) after setting
const FetchedCategories = response.data OR response.data[0].categoryId , since its an array I get this error in the terminal
WARN Possible Unhandled Promise Rejection (id: 4):
TypeError: undefined is not an object (evaluating 'response.data')
You are using await and .then .catch at the same time. This won't allow you to catch errors using .catch. You need to use a try/catch block to handle the error. For example, you can re-write the function as follow:
...
try {
const response = await axios(options)
const fetchedCategories = response.data[0];
return fetchedCategories;
// or
return response.data[0];
} catch(err) {
console.log(err)
// do something with the error
}
...
.then returns undefined,.then((response) => console.log()), so then the response returned at const response = await axios(options) is also undefined, a better approach is to use try/catch as suggested in the other answer
export async function getCategories() {
const https = "xxxxxx";
const url = `${https}/api/Category/GetCategories`;
const userToken ="xxxxxxxx"
const authStr = "Bearer ".concat(userToken);
const options = {
method: "POST",
headers: {
Authorization: authStr,
},
url: url,
};
const response = await axios(options)
// this returns undefined (response) => console.log()
//.then((response) => console.log(response.data[0].categoryName))
.catch((error) => console.log(error.toJSON()));
const fetchedCategories = response.data[0];
console.log(
"🚀 ~ file: menu.js:27 ~ getCategories ~ fetchedCategories",
fetchedCategories
);
return fetchedCategories;

How can I include response data to axios response?

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.

How to change this promise returned function into an async await?

Initially I write my code with promise based script .then().catch
But when I tried to change it into the async await function. Its not working anymore.
Please someone help me with this.
My Old Code Which is working
export const fetchToken = (params) => {
return (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
return axios
.post(`/api/token`, params, config)
.then((res) => {
tokenData = res.data.access_token;
dispatch({
type: LOGGED_IN,
payload: res.data,
});
})
.catch((err) => {
console.log(err);
alert('Provided username and password is incorrect');
throw err;
});
};
};
As you can see in the above code the function is returning a promise. But When I try to change it into async await
My simulator is give me Unexpected reserved work await Error
Here is my async await code in redux
export const fetchToken = async (params) => {
return (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
try {
const response = await axios.post(`/api/token`, params, config);
const data = await response.json();
tokenData = data.access_token
dispatch({ type: LOGGED_IN, payload: res.data})
} catch {
console.log(err);
alert('Provided username and password is incorrect');
}
};
};
Your async is applied to the wrong function, it should be on the dispatch function
export const fetchToken = (params) => (
async (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
try {
const response = await axios.post(`/api/token`, params, config);
const data = await response.json();
tokenData = data.access_token
dispatch({ type: LOGGED_IN, payload: res.data})
} catch {
console.log(err);
alert('Provided username and password is incorrect');
}
};
);
NB: I've removed the braces; arrow function return is implied https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

How to get the result AXIOS in another function?

I am trying to get the result of the AXIOS query, in another function, but as a result I get Promise. Tell me how to get JSON?
export const get = async (url) => {
await axios({
method: 'get',
url: url,
credentials: 'include',
mode: 'cors'
})
.then(response => { return response.data});
}
export const getData = async () => {
await get('http://localhost:7070/data');
}
export const getResult= () => {
let res = api.getData();
return {
type: "TEST",
payload: res
}
}

Unable to get response using fetch in React

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)));

Resources