Axios get data from API - React.js - reactjs

I am using axios to get data from an API, I am trying to do something very simple and I have done it before.
I can see on the console that my request was made but I cant output the data or a console.log() message.
componentDidMount() {
axios.get("https://dog-api.kinduff.com/api/facts")
.then( response => {
console.log("Facts: ")
this.setState({DogFact:response.data})
})
.catch( err => {
this.setState({error:err.data.message})
})
}
The response from the api is an object with an array.
{facts["fact written here"]}
It should be very simple but If I try that:
axios.get("https://dog-api.kinduff.com/api/facts")
.then( response => {
console.log("Facts: ", response) //This wont show up on the console
this.setState({DogFact:response.facts[0]}) //This wont work.
})
I dont really understand what might be wrong.
Could someone maybe help me out?

add this line in package.json
"proxy": "https://dog-api.kinduff.com/api/"
then in your axios call change it to this:
axios.get("/facts")
.then( response => {
console.log("Facts: ", response)
this.setState({DogFact:response.facts[0]})
});

Related

Api fetch responses Blob structure in React Native app

I'm consuming a web api from my React Native Android project. After updating my react-native version to 0.60.3 my response data is not returning JSON, it returns Blob data structure.
This is what I get from then(res=>{...})
Please look at the image
Screen-Shot-2019-07-18-at-17-25-10.png
The _bodyInit object was returning JSON. But now it returns Blob that I can not reach from Js code.
I tried using functions res.json(), res.text()
They worked! But this time I just got data inside the _bodyInit. I can not reach other parameters like ok, header etc.
This is what I've tried. Like I said, it works. But it returns response with just my data, not other parameters like ok, headers etc.
.then((res) => res.json())
.then((res) => {
if (res.ok) {
// No 'ok' element anymore after .json()
}
});
In the 'devtools' if I click the '_bodyInit' object. Simulator gives error below.
Screen-Shot-2019-07-18-at-17-32-49.png
Do you have any idea to solve this issue?
Thanks in advance!
ok property is with response before you call json method on it. If your response contains json, call json to serialize body as json, if response contains blob, call .blob to serialize body as blob. See more proerties of Response here.
.then((res) => {
console.log("response.ok", res.ok)
// print headers,
console.log("headers", res.headers.forEach(item=>console.log(item)))
// if response if json, call res.json
return res.json()
})
.then((res) => {
// here you will only get json data, not other properties.
console.log("json data is ", res)
});
SOLVED
I found two way to solve this problem.
Using .then() after using .json()
.then((res) => {
if (res.ok) {
res.json().then(res=>{
console.log(res)
})
} else console.log("not ok")
});
Using async and await
.then(async res => {
if(res.ok) {
const response = await res.json()
console.log(response)
} else console.log("not ok")
})
That would be great to see other solutions from you. Thanks.

How to handle api error in react and show custom log

componentDidMount() {
let url = FormatUrl(`/user/`)
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data)
}).catch(err => {
if (err){
console.log('has error')
}
})
}
Here i am trying to fetch data from a wrong api.
And it is throwing below error.
Home.jsx:20 GET http://127.0.0.1:8000/user/ net::ERR_CONNECTION_REFUSED
I
Is there any way to hide this error and display a simple message in console without throwing
exceptions.
The promise isn't rejected by the fetch API simply because it fails to reach the endpoint. What you need to do is check the response in your first .then(). You have response.status which returns the status code, or you could use response.ok which returns true if the status code is within the 200-299 interval.
A more detailed explanation can be found here

How to fetch data with axios for a placeid in Google maps and React?

I have an array in state restaurantsFetchedFromGoogle which currently stores 20 placeids previously fetched from google maps. They are stored in the array as such:
0:"ChIJTb1qU315MhMRiL7pihnMWfg"
1:"ChIJGZ0jXCCNMRMRrH8VHRAgEYE"
2:"ChIJQ5jaX8eMMRMRnRoZxl6X95w"
...
19:"ChIJQ5jaX8errrMRnRoZxl6X95w"
Now I'm trying to iterate the array with an Axios get request such as:
componentDidMount(){
navigator.geolocation.getCurrentPosition(position=>{
this.setState({geoLat:position.coords.latitude,geoLng:position.coords.longitude});
axios.get(`https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${position.coords.latitude},${position.coords.longitude}&radius=50000&keyword=recensioni&type=ristorante&keyword=cena&key=MYAPIKEY`)
.then(response => this.setState({restaurantsFetchedFromGoogle:response.data.results}));
});
this.state.restaurantsFetchedFromGoogle.map(item=>{
axios.get(`https://maps.googleapis.com/maps/api/place/details/json?placeid=${item.place_id}&key=AIzaSyCZ7rgMN34kWkGvr8Pzkf_8nkT7W6gowBA`)
.then(response => this.setState({placeId:response.data}))
.catch(err =>{
console.log(err);
console.log(err.response.data.error);
});
});
axios.get('/restaurants.json')
.then(response =>this.setState({restaurants:response.data}));
}
First and third axios request goes through but not the second one. What am I doing wrong?
Add an error handler to log the error message! That should tell you why the request is failing.
this.state.restaurantsFetchedFromGoogle.map(item=>{
axios.get('https://maps.googleapis.com/maps/api/place/details/json?placeid='+
item + '&key=MYAPIKEY')
.then(response => this.setState({placeId:response.data}))
.catch(err => {
console.log(err) //Axios entire error message
console.log(err.response.data.error) //Google API error message
})
});
Even without the .catch - you can use the chrome dev tools to see the error under the Network tab in the dev tools.
If you still have issues after - post the specific error message and I'll take a look.

Axios not retreiving data from REST service

Im using React with axios to read some data from my backend.
I have a BetBuilder js using axios to read like this:
componentDidMount() {
axios.get('http://localhost:8080/api/matches/')
.then(response => {
console.log("Dentro do didmount");
this.setState({ matches: response.data._embedded.matches });
console.log(this.state.matches);
console.log("Dentro do didmount");
});
Everything works fine here. So in my render method i pass this data to a Match component:
var matches = this.state.matches.map(match =>
<Match key={match._links.self.href} match={match}/>
);
In my Match.js class, I try to retrieve other data with axios. But it just doesnt work. In my debug it never enters on the response function.
const awayUrl = this.props.match._links.away.href;
const homeUrl = this.props.match._links.home.href;
axios.get("http://localhost:8080/api/matches/4/away")w
.then(response => {
console.log("Dentro do away");
this.setState({ away: response.data._embedded });
console.log(this.state.away);
console.log("Dentro do away");
})
.catch((error) => {
console.log("error",error)
});
What Im missing? Theres something on the Axios lifecycle that i cant use it in the same request? Why this axios.get method is never called, and dont throws any exception too?
Thanks

Better ways to handle REST API call in Redux

In my app, I need to call several REST API endpoints:
// The UI Class
class LoginForm extends Component {
handleSubmit(){
store.dispatch(login(username, password));
}
}
// An action
function login(username, password){
return dispatch => {
fetch(LOGIN_API, {...})
.then(response => {
if (response.status >= 200 && response.status < 300){
// success
} else {
// fail
}
})
}
}
The gist is above and easy to understand. User triggers an action, an ajax call to the corresponding endpoint is made.
As I am adding more and more API endpoints, I end up with a bunch of functions similar to the skeleton of the login function above.
How should I structure my code in such a way that I don't repeat myself with duplicate ajax functions?
Thanks!
I strongly suggest you to read this popular github sample project. At first it is hard to understand but don't worry and continue to read and realize what is happening in that.
It uses very clear and simple way to handle all of your API calls. when you want to call an API, you should dispatch an action with specific structure like this:
{
types: [LOADING, SUCCESS, FAIL],
promise: (client) => client.post('/login', {
data: {
name: name
}
})
}
and it will handle these kind of actiona by a custom middleware.
The way I handle a similar situation is to have 2 wrapper for API calls:
function get(url) {
return fetch(url)
.then(response => {
if(response.status >= 200 && response.status < 300) {
return response
}
else {
let error = new Error(response.statusText)
error.response = response
throw error
}
})
.then(response=> response.json())
}
This wrapper will take a url and return the json data. Any error that happens (network, response error or parsing error) will be caught by the .catch of get
A call basically looks like that:
get(url)
.then(data => dispatch(someAction(data)))
.catch(error => dispatch(someErrorHandler(error)))
I also have a post wrapper that in addition sets the header for CSRF and cleans the data. I do not post it here as it is quite application-related but it should be quite ovious how to do it.

Resources