Unable to get response using fetch in React - reactjs

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

Related

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
}
}

Call two fetch function with setState in between

I am trying to call two fetch APIs to store the information.
After first API call to cloudinary I get the URL back, which I want to store in state before hitting second API to store info in database. I am getting setAddOnData undefined error. While I try to make second API call , code functions properly for single API
const onSubmit = e => {
e.preventDefault();
console.log(fileInputRef.current.files[0]);
const myNewCroppedFile = fileInputRef.current.files[0];
console.log(myNewCroppedFile);
const formData = new FormData();
formData.append('file', myNewCroppedFile);
formData.append('upload_preset', 'xprl6rwq');
const options = {
method: 'POST',
body: formData
};
const addOnBody = JSON.stringify({ itemName, itemIconURL, itemPrice });
const config = {
headers: {
'Content-Type': 'application/JSON'
}
};
const option2 = {
method: 'POST',
body: addOnBody
};
return fetch(
'https://api.Cloudinary.com/v1_1/antilibrary/image/upload',
options
)
.then(res => res.json())
.then(res =>
setAddOnData({
...addOnData,
itemIconURL: res.secure_url
})
)
.then(fetch(`/api/v1/addOn`, option2, config))
.then(res => res.json());
};
const [addOnData, setAddOnData] = useState({
addOnCategory: '',
itemName: '',
itemPrice: '',
itemIconURL: '',
itemIconFileName: '',
step: 1
});
setState calls are asynchronous. When you run your second fetch call, the setAddOnData hasn't necessarily updated the addonData variable yet. You'd be best off moving the second fetch call to a useEffect which is dependent on the data returned from your first fetch call.
const addOnBody = JSON.stringify({ itemName, itemIconURL, itemPrice });
const config = {
headers: {
'Content-Type': 'application/JSON'
}
};
const option2 = {
method: 'POST',
body: addOnBody
};
const onSubmit = e => {
...
return fetch(
'https://api.Cloudinary.com/v1_1/antilibrary/image/upload',
options
)
.then(res => res.json())
.then(res =>
setAddOnData({
...addOnData,
itemIconURL: res.secure_url
})
)
};
useEffect( () => {
fetch(`/api/v1/addOn`, option2, config)
.then(res => res.json());
},[addOnData.itemIconURL])

Unhandled Rejection (TypeError): Cannot read property 'error' of undefined

I'm fairly new to React and I've been trying to create a SignUp page, however, I'm stuck in this error. Can someone give me any indication on what I should do in order to solve this error?
Signup Method:
// = Action =
// Sign up
export const signup = user => {
return fetch(
`${API}/signup`,
{
method: 'POST',
headers: {
Accept:'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(user)
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
}
Rewrite Signup method (ps: I only changed the .catch handler)
`
// Sign up
export const signup = user => {
return fetch(
`${API}/signup`,
{
method: 'POST',
headers: {
Accept:'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(user)
})
.then(response => {
return response.json();
})
.catch(err =>
console.log(err));
return err;
}
`
You need to wrap up your fetch logic inside a Promise to return a value to the caller.
export const signup = user => {
return new Promise((resolve, reject) => {
fetch(`${API}/signup`,
{
method: 'POST',
headers: {
Accept:'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(user)
})
.then(response => response.json())
.then(jsonData => resolve(jsonData))
.catch(err => resolve({error: `something went wrong err : ${err}`}));
})
}
signup(user).then(data => {
if (data.error) {
// handle error case
} else {
// handle success case
}
})
Now your signup method will return a value. Your data variable won't be undefined anymore.
I hope it helps, feel free to add comments or ask me more details

How to make common API call function using fetch

I am trying to make common function which will handle all of my API calls from anywhere
I am using react": "^16.8.6" and fetch for making api call
So far what i have figure out to do
is
Helper.js
export function ApiHelper(url, data = {}, method = 'POST') {
let bearer = 'Bearer ' + localStorage.getItem('user_token');
var promise = fetch(url, {
method: method,
withCredentials: true,
// credentials: 'include',
headers: {
'Authorization': bearer,
'X-FP-API-KEY': 'chaptoken',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(
(result) => {
console.log(result);
},
(error) => {
error = error;
}
)
}
export function AnyOtherHelper() {
return 'i am from helper function';
}
And here is from where i am calling this function
componentDidMount() {
let url = `http://localhost/project/api/getdata`;
let op = ApiHelper(url);
}
when I console result in then i am getting appropriate result but what i want to return that response how can i do this part is troubling me
Even i have try to store the result in global variable and it is not working.
Also i have to return the response only when promise is resolved.
You are making an async call from your helper function which means, you will have to return promise from your helper function like this -
export function ApiHelper(url, data = {}, method = 'POST') {
let bearer = 'Bearer ' + localStorage.getItem('user_token');
return fetch(url, { // Return promise
method: method,
withCredentials: true,
// credentials: 'include',
headers: {
'Authorization': bearer,
'X-FP-API-KEY': 'chaptoken',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then((result) => {
console.log(result);
return result;
}, (error) => {
error = error;
})
}
USAGE
componentDidMount() {
let url = `http://localhost/project/api/getdata`;
ApiHelper(url)
.then(resposnse => {
console.log(resposnse);
});
}

React Native refreshing data

I'm trying to refresh some data when users re-vistis the screen. The way im using other places and it works. but can't figure out why this won't fly on this screen?
componentDidMount = () => {
this.props.navigation.addListener('didFocus', this.handleDidFocus)
}
async handleDidFocus() {
...
}
This is how I load data the first time and want to load it again when users revisits.
componentWillMount() {
this.getGroupAccepted();
}
async getGroupAccepted() {
if (this.state.token == null) {
var token = await AsyncStorage.getItem("token");
this.setState({ "token": token });
}
fetch('https://.../api/group/getActive', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
token: this.state.token
})
})
.then(response => response.json())
.then((data) => {
this.setState({
groups_accepted: data.groups_active,
loading: false,
});
})
.catch((error) => {
console.error(error);
});
}
This is what worked. Now when a user revisits the screen it loads the data once again.
componentDidMount = () => {
this.props.navigation.addListener('didFocus', this._handleDataChange)
}
_handleDataChange = () => {
this.getGroupAccepted();
}

Resources