Reputation: 328
Yo guys, getting error 'contacts.map is not a function' not sure why is that ? just starting in react maybe missing something obvious. I'm getting the data when I console log all good. code below:
import React, { Component } from 'react'
import axios from 'axios';
class Contacts extends Component {
constructor(){
super();
this.state = {
contacts: [],
}
}
componentDidMount(){
axios.get('url')
.then(response => {
this.setState({ contacts: response.data });
})
.catch(function (error) {
console.log(error);
})
}
render() {
const { contacts } = this.state
return(
<div>
{contacts.map(contact => (
<h1>contact.hello</h1>
))}
</div>
)
}
}
export default Contacts;
Apparently its an object not an array...
How can i render this object then?
It has one property for now but will have more later on: tried JSON.stringify(obj)
{hello: "test"}
Upvotes: 2
Views: 149
Reputation: 11800
From react docs:
Note:
These methods are considered legacy and you should avoid them in new code:
- UNSAFE_componentWillMount()
When you want to wrap an object you can simply wrap it in brackets
class Contacts extends Component {
constructor() {
super();
this.state = {
contacts: [],
}
}
componentDidMount() {
axios.get('url')
.then(({ data }) => {
this.setState({ contacts: [data] });
})
.catch((error) => {
console.log(error);
});
}
render() {
const { contacts } = this.state;
return (
<div>
{contacts.map(contact => (
<h1 key={/* unique key */}>contact.hello</h1>
))}
</div>
);
}
}
Upvotes: 2
Reputation: 34014
Since the contacts is an object I would recommend you to do Object.keys and then .map on it so that you can get object keys and it’s values.
One more thing never forget to add unique key to the parent jsx element when you iterate array of data or an object like below.
<div>
{Object.keys(contacts).map((name, index) => (
<h1 key={'Key'+index}>{contacts[name]}</h1>
))}
</div>
Upvotes: 3
Reputation: 314
Use async await to get the response before the component is mounted
import React, { Component } from 'react'
import axios from 'axios';
class Contacts extends Component {
constructor(){
super();
this.state = {
contacts: [],
}
}
async componentWillMount(){
const response = await axios.get('url')
this.setState({ contacts: response.data })
}
render() {
const { contacts } = this.state
return(
<div>
{contacts.map(contact => (
<h1>contact.hello</h1>
))}
</div>
)
}
}
export default Contacts;
Upvotes: 0
Reputation: 76910
The problem is that you set contacts
to response.data
, which evidently it's not an array.
componentDidMount
fires after the component is mounted and tries to get the string 'url'. When state is updated, the component is redrawn and it gives the error.
Upvotes: 5