user9810370
user9810370

Reputation: 21

TypeError: this.state.data.map is not a function

I'm a noob with React-native, I am trying to make my code hit a particular API and then display a piece of information from the JSON that is returned but for some reason, the JSON that is returned from this api doesn't work even though it works from other apis. I've been struggling for a couple of days now and I'm just confused. Can anyone show me what I'm doing wrong?

import React, { Component } from 'react';
import { FlatList, StyleSheet, Text, View} from 'react-native';
import axios from 'axios';

export default class App extends Component {
  state = { data: [] };

  componentDidMount() {
  axios.get('https://dvlasearch.appspot.com/AccountInfo?apikey=DvlaSearchDemoAccount')
    .then(response => this.setState({ data: response.data }));
  }

  renderData() {
    return this.state.data.map(data => <Text>{data.client}</Text>);
  }

  render() {
    console.log(this.state);

    return (
      <View>
        {this.renderData()}
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    marginTop: 15,
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});

Upvotes: 2

Views: 7629

Answers (4)

endlessCode
endlessCode

Reputation: 1405

just add

 constructor(props) {
    super(props);

    this.state = { albums: [] };
 }

Upvotes: 0

needsleep
needsleep

Reputation: 2725

You correctly set your state variable "data" as an array

state = { data: [] };

However the API you're calling doesn't return array data but it is actually an object. So after fetching you're basically turn your data array into an object like this:

{
    "status":"success",
    "client":"Demo account",
    "usedCredits":31325,
    "totalCredits":1000000,
    ... more attributes
}

Then you try to render this data as if it was an array using the map function but you don't have an array so map is not a method you can use.

Solution: Set the correct data from your API to your state variable and make sure it's an array.

UPDATE

By your comment I understand that you want to print the object data since the response doesn't return an array. My suggestion would be to process the data to an array the moment you get them from your API call like this:

componentDidMount() {
    axios.get('https://dvlasearch.appspot.com/AccountInfo?apikey=DvlaSearchDemoAccount')
        .then(response => {
            let details = [];

            for (var i in response.data) {
                details.push({ name: i, value: response.data[i] })
            }

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

and then simply render them using the map function like this:

render() {
    console.log(this.state);

    return (
      <View>
        {
          this.state.data.map(item => {
            return <Text>{item.name} - {item.value}</Text>
          })
        }
      </View>
    );
  }

Of course you need to adjust this to your needs

Upvotes: 2

Prabhu
Prabhu

Reputation: 1057

You can use the componentDidMount to componentWillMount

componentWillMount() {
  axios.get('https://dvlasearch.appspot.com/AccountInfo?apikey=DvlaSearchDemoAccount')
    .then(response => this.setState({ data: response.data }));
  }

Upvotes: 0

Ravi
Ravi

Reputation: 35589

assign value to your state in constructor(props)

constructor(props)
{
    this.state = {
        data: []
    }
}

Upvotes: 4

Related Questions