I am trying to make a request to the FourSquare API which desires a time object being sent in the format of YYYYMMDD. I have written a function that produces the time object however I am having issues using it within my React app.
I make a call within my Profile
component:
'use strict'
import React, { Component } from 'react'
import request from 'superagent'
import TimeService from './services/time'
import config from './config'
class Profile extends Component {
componentDidMount() {
TimeService.getCurrentTime((err, currentDate) => {
this.setState({
time: currentDate
})
})
}
componentWillMount() {
let currentTime = this.state.time
let venue = '4dd64e9de4cd37c8938e7b83'
//let venue = this.props.venueId
let clientId = config.CLIENT_ID
let clientSecret = config.CLIENT_SECRET
request.get(`https://api.foursquare.com/v2/venues/${venue}/hours/?\&client_id=${clientId}&client_secret=${clientSecret}&v=${currentTime}`)
.accept('json')
.end((err, res) => {
if(err) return
let result = res.body
console.log(res.body)
console.log(result.response.hours.timeframes)
})
}
When I load app in Chrome I have the error message of: bundle.js:44492 Uncaught TypeError: Cannot read property 'time' of null
My guess is that I need to re-order the functions within the component mounting methods, however I am unsure how to.
Various methods are executed at specific points in a component's lifecycle.
componentWillMount
is executed once before the initial rendering occurs.
componentDidMount
is executed once after the initial rendering.
You are setting your state when the component is mounted in componentDidMount
but using it before in componentWillMount
.
So when you're using:
let currentTime = this.state.time
It's not defined yet so you're getting an Cannot read property 'time' of null
.
You should set your state in componentWillMount
, the render()
will see the updated state and will be executed only once despite the state change.
After that, once the component is mounted, you can execute your call to the Foursquare API, your time
property in the state will be defined so it'll no longer trigger an error.
You can get more informations regarding components lifecycle in the documentation.
This documentation also states that the preferred method to send AJAX requests is componentDidMount
.
If you want to integrate with other JavaScript frameworks, set timers using setTimeout or setInterval, or send AJAX requests, perform those operations in this method.