guribe94
guribe94

Reputation: 1543

React native - object exists in state but is undefined when I try to access it

I'm trying to query an API to use the data in a react native app but am running into a problem with accessing data I store in the state. Basically, I am trying to access a markets object which is stored in the state. If I examine the state, I see the markets object is properly set. However, as soon as I try to do anything with the markets object, I encounter an error that says Cannot read property 'markets' of null.

Why is this happening and how can I fix this issue?

I included the code that causes the issue below. I appreciate any suggestions.

export default class cryptoTracker extends Component {


  constructor(props) {
    super(props);

  this.opts = {
      baseUrl: 'https://bittrex.com/api/v1.1',
      apikey: 'APIKEY',
      apisecret: 'APISECRET',
    };
    this.updateMarkets();
  }


  updateMarkets(){
   axios.get(this.opts.baseUrl + '/public/getmarkets').then((response) => { 
        this.setState({'markets' : response.data.result});
        }
      ).catch((error) => {
        console.log(error.name)
        console.log("Error");
      });

  }

 render() {
  console.log("The state is below");
  console.log(this.state);
//This line causes the issue
  console.log(this.state.markets);


     return(
     <View>
     </View>);
}
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('cryptoTracker', () => cryptoTracker);

Upvotes: 3

Views: 1018

Answers (1)

Mayank Shukla
Mayank Shukla

Reputation: 104379

Reason is, you didn't define the state variable in constructor. Api call be asynchronous so when you get data and do setState, after that only state will be available (before that state will be null), render will get executed before that and when it will try to access the value this.state.makers, it is throwing the error:

Cannot read property 'markets' of null

Changes:

1. Define the state object and define the makers inside that, like this:

constructor(props) {
     super(props);
     this.state = {
         makers: {}
     }
     this.opts = {
       baseUrl: 'https://bittrex.com/api/v1.1',
       apikey: 'APIKEY',
       apisecret: 'APISECRET',
     };
}

2. Use componentDidMount lifecycle method and do the api call inside that, like this:

componentDidMount(){
   this.updateMarkets();
}

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. Setting state in this method will trigger a re-rendering.

3. Name of the component must start with a uppercase letter, so use CryptoTracker instead of cryptoTracker.

Upvotes: 3

Related Questions