Accepted answer

The .map function is only available on array.
It looks like data isn't in the format you are expecting it to be (it is {} but you are expecting []).

this.setState({data: data});

should be

this.setState({data: data.conversations});

Check what type "data" is being set to, and make sure that it is an array.

Modified code with a few recommendations (propType validation and clearInterval):

var converter = new Showdown.converter();

var Conversation = React.createClass({
  render: function() {
    var rawMarkup = converter.makeHtml(this.props.children.toString());
    return (
      <div className="conversation panel panel-default">
        <div className="panel-heading">
          <h3 className="panel-title">
        <div className="panel-body">
          <span dangerouslySetInnerHTML={{__html: rawMarkup}} />

var ConversationList = React.createClass({
 // Make sure is an array
  propTypes: {
    data: React.PropTypes.array.isRequired
  render: function() {            =;
    var conversationNodes =, index) {

      return (
        <Conversation id={} key={index}>

    return (
      <div className="conversationList">

var ConversationBox = React.createClass({
  loadConversationsFromServer: function() {
    return $.ajax({
      url: this.props.url,
      dataType: 'json',
      success: function(data) {
        this.setState({data: data.conversations});
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
  getInitialState: function() {
    return {data: []};

 /* Taken from
    clears all intervals after component is unmounted
  componentWillMount: function() {
    this.intervals = [];
  setInterval: function() {
    this.intervals.push(setInterval.apply(null, arguments));
  componentWillUnmount: function() {;

  componentDidMount: function() {
    this.setInterval(this.loadConversationsFromServer, this.props.pollInterval);
  render: function() {
    return (
      <div className="conversationBox">
        <ConversationList data={} />

$(document).on("page:change", function() {
  var $content = $("#content");
  if ($content.length > 0) {
      <ConversationBox url="/conversations.json" pollInterval={20000} />,


try componentDidMount() lifecycle when fetching data


Add this line.

var conversationNodes>0 &&, index){.......}

Here we are just checking the length of the array. If the length is more than 0, Then go for it.


'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': '2',

I delete that code line in setting it to fix it


You don't need an array to do it.

var ItemNode = {
return (
   <ComponentName title={itemData.title} key={} number={}/>


You need to convert the object into an array to use the map function:

const mad = Object.values(this.props.location.state);

where this.props.location.state is the passed object into another component.


As mentioned in the accepted answer, this error is usually caused when the API returns data in a format, say object, instead of in an array.

If no existing answer here cuts it for you, you might want to convert the data you are dealing with into an array with something like:

let madeArr = Object.entries(initialApiResponse)

The resulting madeArr with will be an array of arrays.

This works fine for me whenever I encounter this error.


I had a similar error, but I was using Redux for state management.

My Error:

Uncaught TypeError: is not a function

What Fixed My Error:

I wrapped my response data in an array. Therefore, I can then map through the array. Below is my solution.

const ProfileAction = () => dispatch => {
  dispatch({type: STARTFETCHING})
    .get(`http://localhost:3333/api/users/${id here}`)
    .then((res) => {
        // wrapping in an array like below is what solved the error 
        dispatch({type: FETCHEDPROFILE, payload: []})
    }) .catch((error) => {
        dispatch({type: FAILDFETCH, error: error})

 export default ProfileAction


You should try this:

const updateNews =  async()=>{

    const res= await  fetch('')
    const data =await res.json();


Create an array from props data.

let data = Array.from(

Then you can use it like this:

{, index) => {
return (<span key={index}>{itm}</span>)


If you're using react hooks you have to make sure that data was initialized as an array. Here's is how it must look like:

const[data, setData] = useState([])


Sometimes you just have to check if api call has data returned yet,

{ && ( => /* render data */)}


I had the same problem. The solution was to change the useState initial state value from string to array. In App.js, previous useState was

const [favoriteFilms, setFavoriteFilms] = useState('');

I changed it to

const [favoriteFilms, setFavoriteFilms] = useState([]);

and the component that uses those values stopped throwing error with .map function.


It happens because the component is rendered before the async data arrived, you should control before to render.

I resolved it in this way:

render() {
    let partners = this.props && > 0 ?>
            <li className = "partners" key={}>
                <img src={p.img} alt={}/> {} </li>
        ) : <span></span>;

    return (
  • Map can not resolve when the property is null/undefined, so I did a control first

this.props && > 0 ?


More generally, you can also convert the new data into an array and use something like concat:

var newData =[data]);  
this.setState({data: newData})

This pattern is actually used in Facebook's ToDo demo app (see the section "An Application") at


You need to create an array out of, like so:

data = Array.from(;

then will be able to use function

Related Query

More Query from same tag