i'm getting absolutely no response from calling my api in react:
constructor(props) {
super(props);
this.state = {
team: {}
}
}
getData() {
axios.get('http://game.test/api/characters')
.then(response => this.setState({ team: response.data.characters }));
}
componentDidMount() {
this.getData();
console.log(this.state);
}
the state is empty and if I console.log anything in .then, the console is also empty (like that part of the code is not reachable).
Also on Network tab everything seems to be okay (status 200 & correct data).
setState is async so in console.log(this.state) will execute before this.getData() in the componentDidMount. if you want to log the fetch result/error put log in getData with async/await:
constructor(props) {
super(props);
this.state = {
team: {},
error: ""
}
}
getData = async () => {
await axios.get('http://game.test/api/characters')
.then(response => this.setState({ team: response.data.characters }))
.catch(error => this.setState({error: error}))
console.log(this.state) //log fetch result/error
}
componentDidMount() {
this.getData();
console.log(this.state) //log init state
}
Try this, it will work
App.js
import Child from "./Comp/Chid";
export default function App() {
return (
<div className="App">
<Child />
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
Comp/Child.js
import React from "react";
import axios from "axios";
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
team: {}
};
}
async getData() {
await axios
.get("https://jsonplaceholder.typicode.com/posts")
.then((response) => {
console.log(response);
this.setState({ team: response.data.characters });
});
}
componentDidMount() {
this.getData();
console.log(this.state);
}
render() {
return <div>Hello</div>;
}
}
export default Child;
i dont see much problem with your code try the following if it helps
first try to console.log(response) before updating the state
try async getData () and await axios since you are fetching asynchronous operation
Related
I have this bellow App.js code:
import React, { Component } from 'react';
import axios from 'axios'
class Axios extends Component {
constructor() {
super();
this.state = {
item : '',
}
}
componentDidMount() {
axios.get('https://restcountries.com/v3.1/capital/lima')
.then( response => {
const data = response.data.map(( data )=>{
this.setState({
item : data
});
});
})
.catch( error => {
alert( error );
});
}
prepare() {
console.log( this.state.item );
}
render() {
return (
<div>{this.prepare()}</div>
)
}
}
export default Axios;
My goal is to get the common name from this API: https://restcountries.com/v3.1/capital/lima
Now on componentDidMount() method, I need to set the API return data to the item state so that I can loop through using the prepare method.
But I don't have any idea how to set the API return array JSON data to the item state?
Update your state.item to a blank array.
constructor() {
super();
this.state = {
item : [],
}
}
In componentDidMount(), update the code to accept response :
componentDidMount() {
axios.get('https://restcountries.com/v3.1/capital/lima')
.then( response => {
this.setState({
item : response.data
});
})
.catch( error => {
alert( error );
});
}
In render(), you can use map on state.item and can loop on it.
render() {
return (
<div>{this.state.item.map(data,index)=>(
//some UI mapping to each `data` in `item` array
)}</div>
)
}
You just have to do assing response.data to item as:
Live Demo
componentDidMount() {
axios
.get("https://restcountries.com/v3.1/capital/lima")
.then((response) => {
this.setState({
item: response.data
})
})
.catch((error) => {
alert(error);
});
}
You should check this out.
import React, { Component } from "react";
import axios from "axios";
class Axios extends Component {
constructor() {
super();
this.state = {
item: []
};
}
componentDidMount() {
axios
.get("https://restcountries.com/v3.1/capital/lima")
.then((response) => {
this.setState({
item: response && response.data
});
})
.catch((error) => {
alert(error);
});
}
prepare() {
return <div>{console.log("Item", this.state.item)}</div>;
}
render() {
return <div>{this.prepare()}</div>;
}
}
export default Axios;
Here is my React js code for a single API call for a date range picker. now I want to call multiple API in React with componentDidMount Method is it possible if yes how can do that
import React,{ Component} from "react";
import axios from 'axios'
class PostList extends Component{
constructor(props) {
super(props)
this.state = {
posts: []
}
}
componentDidMount(){
axios.get('http://127.0.0.1:8000/betweendays')
.then(response => {
this.setState({
posts:response.data
})
console.log(response.data)
})
}
render() {
const {posts} = this.state
return (
<div>
<h1>get call in React js</h1>
{
posts.map(post => <div key = {post.id}>{post.id} </div>)
}
</div>
)
}
}
export default PostList```
Using .then() method to create chain of the requests..
componentDidMount() {
axios.get('http://127.0.0.1:8000/betweendays')
.then(response => {
this.setState({
posts: response.data
})
return response.data; // returning response
})
.then(res => {
// do another request Note we have the result from the above
// getting response returned before
console.log(res);
})
// Tag on .then here
.catch(error => console.log(error))
}
You can add more apis in componentDidMount as u want.
componentDidMount(){
axios.get('http://127.0.0.1:8000/betweendays')
.then(response => {
this.setState({
posts:response.data
})
console.log(response.data)
})
axios.get('link')
.then(response => {
this.setState({
posts:response.data
})
console.log(response.data)
})
}
I'm making a call to a getTime function which returns the datetime, but for some reason the state I specify is not being updated, am I misunderstanding how this works? Do I need to await the result?
import * as React from 'react';
import {getTime} from '../utilities/time-helper'
export default class Landing extends React.Component {
constructor(props) {
super(props);
this.state = {
london: null,
paris: null
};
}
componentDidMount() {
this.setState({ london: getTime("Europe/London") });
this.setState({ paris: getTime("Europe/Paris") });
}
render() {
return (
<div>
<h1>London Time: {this.state.london}</h1>
<h1>Paris Time: {this.state.paris}</h1>
</div>
);
}
}
// time-helper.js
export function getTime(timezone) {
let url = 'http://worldtimeapi.org/api/timezone/' + timezone;
fetch(url)
.then(res => res.json())
.then((out) => {
return out.datetime
})
.catch(err => { throw err });
}
Yes, exactly, it's a fetch, so you gotta wait for the result and set the state only then, so you could do smth like:
componentDidMount() {
getTime('Europe/London')
.then((response) => this.setState({ london: response });
}
I'd like to call getAlbums() method so I can use the data from the get request and display album data on the client side. I don't know where to call it though. I tried to call it in render() but it creates an infinite loop.
Albums.js
import React, { Component } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";
import AlbumCard from "./AlbumCard";
export class Albums extends Component {
constructor(props) {
super(props);
this.state = { albums: [] };
this.getAlbums = this.getAlbums.bind(this);
}
async getAlbums() {
const {
match: { params },
} = this.props;
console.log(params.id);
try {
const res = await axios.get(
`http://localhost:4000/albums/${encodeURIComponent(params.id)}`,
{
params: {
id: params.id,
},
}
);
console.log(`Returned album data from the server: ${res}`);
this.setState({ albums: res.data });
} catch (err) {
console.log(err);
}
}
render() {
return (
<>
<div className="container" style={{ color: "white" }}>
hello
</div>
</>
);
}
}
export default Albums;
I wanna do something like this inside the div.
this.state.albums.map((album) => (<AlbumCard img={album.img}/>))
The reason you get an infinite loop is because you're calling setState in render. Here is what's happening behind the scenes:
1.getAlbums is called in the render method.
2.The function triggers setState.
3.setState causes re-render.
4.In the render method, getAlbums is called again.
Repeat 1-4 infinitely!
Here's is what you could do:
Create a button and bind getAlbums as a method to the onClick event handler.
2.Run getAlbums on ComponentDidMount like so:
componentDidMount() {
this.getAlbums();
}
componentDidMount() is the best place for making AJAX requests.
The componentDidMount() method will set state after the AJAX call fetches data. It will cause render() to be triggered when data is available.
Here is the working example with componentDidMount()
import React, { Component } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";
import AlbumCard from "./AlbumCard";
export class Albums extends Component {
constructor(props) {
super(props)
this.state = { albums: [] }
}
componentDidMount() {
axios.get(
`http://localhost:4000/albums/${encodeURIComponent(this.props.id)}`,
{ params: { id: this.props.id } }
)
.then(response => {
console.log(`Returned album data from the server: ${res}`)
this.setState({ albums: response.data })
}
)
.catch(e => {
console.log("Connection failure: " + e)
}
)
}
render() {
return (
<div>
{/* Code for {this.state.albums.map(item => )} */}
{/* render() method will be called whenever state changes.*/}
{/* componentDidMount() will trigger render() when data is ready.*/}
</div>
)
}
}
export default Albums
More information:
https://blog.logrocket.com/patterns-for-data-fetching-in-react-981ced7e5c56/
use componentDidMount()
componentDidMount(){
getAlbums()
}
I'm trying to get a data that is returning from axios get method to a method call on aon object. Instead of returning the value, it's returning the promise. What am I missing here?
import React, { Component } from "react";
import ReactDOM from "react-dom";
import axios from "axios";
import "./styles.css";
class App extends Component {
state = {
totalResults: ""
};
componentDidMount() {
this.setState({
totalResults: this.fetchData()
.then(function(res) {
const r = res.data.totalResults;
return r;
})
.catch(err => console.log("error: ", err))
});
}
fetchData = () => {
return axios.get(
"https://newsapi.org/v2/top-headlines?country=us&apiKey=8d98dac05ec947d1b891832495641b49"
);
};
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button onClick={() => console.log(this.state.totalResults)}>
Click
</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here's the link to codesandbox
Note: This is just a reference code. I can't do setState because I'm trying to call the method from array.map() iterator instead.
Edit:
This is what actually I'm trying to do: codesandbox.io/s/n5m3qyn65l
For some reason it's showing Network Error
Thanks for helping me out.
You should use Promise.all() to fetch all images before updating your articles. Like so:
const res = response.data;
Promise.all(res.map(article => (
this.fetchImages(article.featured_media)
.then(image => ({
title: article.title.rendered,
content: article.content.rendered,
featuredImage: image.guid.rendered
}))
.catch(err => console.log("Error fetching image: ", err))
))
)
.then(articles => this.setState({ articles }))
.catch(err => console.log("Error setting up articles: ", err))
You should setState after getting the response from fetchData() because fetchData() will return promise, which you're setting in the state.
Remember, setState will do assignment only, you can't expect it wait for asynchronous operation. In that case, try async/await
Updated answer:
https://codesandbox.io/s/1r22oo804q
Find the inline comments
// Our basic components state setup
class myComponent extends Component {
constructor(props) {
super(props);
this.state = {
currentSession: {
fullNames: [],
contactInfo: []
}
}}
// Here we make our function to fetch our API data
fetchData()
.then(res => {
let namesData = res.data.name;
let contactData = res.data.email;
this.setState(prevState => ({
currentSession: {
...prevState.currentSession,
fullNames: Object.assign(namesData),
contactInfo: Object.assign(contactData)
}
}));
});
// Since it's an async call, we'll put in in a 'componentDidMount' method
componentDidMount() {
this.fetchData();
}