Search code examples
react-nativetypeerrorreact-native-flatlist

React Native TypeError: Cannot read property 'timeSlots' of undefined


I want to display the selected Date, Start Time, and End Time when user presses the Add Appointment Button. However, when I press the add appointment button, the data gets added to my database but it fails to show it on the FlatList.

Code snippet provided below (If full code is required I can provide it):

export default class FrCreateScreen extends Component {
  addTimeDateAppt() {
    let self = this;
    AsyncStorage.getItem('my_token').then(keyValue => {
      console.log('Freelancer Create Screen (keyValue): ', keyValue);
      axios({
        method: 'post',
        url: Constants.API_URL + 'appointment_f/create_appointment/',
        //responseType: 'json',
        data: {
          app_date_start: this.state.textAppointmentDate,
          start_time: this.state.textAppointmentTime,
          end_time: this.state.textEndTime,
        },
        headers: {
          'X-API-KEY': Constants.API_KEY,
          Authorization: keyValue,
        },
      })
        .then(function(response) {
          this.setState({
            timeSlots: [
              ...this.state.timeSlots,
              {
                apptdate: this.state.textAppointmentDate,
                appttime: this.state.textAppointmentTime,
                endTime: this.state.textEndTime,
              },
            ],
          });
          console.log(response.data);
        })
        .catch(function(error) {
          console.log('Create Error: ', error);
        });
    });
  }

  deleteDateTime = id => {
    const filteredData = this.state.timeSlots.filter(item => item.id !== id);
    this.setState({ timeSlots: filteredData });
  };

  render() {
    return (
      <ScrollView>
        {this.getAppointmentDatePage()}
        {this.getAppointmentTimePage()}
        {this.getEndTimePage()}
        <TouchableOpacity
          style={styles.addContainer}
          onPress={() => this.addTimeDateAppt()}
        >
          <Text style={styles.addText}> Add Appointment </Text>
        </TouchableOpacity>
        <View>
          <FlatList
            data={this.state.timeSlots}
            keyExtractor={({ id }, index) => index.toString()}
            renderItem={({ item, index }) => {
              return (
                <View style={styles.containerList}>
                  <View style={styles.dateList}>
                    <Text style={{ fontWeight: 'bold' }}>Date: </Text>
                    <Text style={styles.textTime}>{item.apptdate}</Text>
                  </View>
                  <View style={styles.row}>
                    <View>
                      <Text style={{ fontWeight: 'bold' }}>Start Time:</Text>
                      <Text style={styles.textTime}>{item.appttime}</Text>
                    </View>
                    <View>
                      <Text style={{ fontWeight: 'bold' }}>End Time:</Text>
                      <Text style={styles.textTime}>{item.endTime}</Text>
                    </View>
                    <TouchableOpacity
                      onPress={() => this.deleteDateTime(item.index)}
                    >
                      <Feather name="trash" style={styles.icon} />
                    </TouchableOpacity>
                  </View>
                </View>
              );
            }}
          />
        </View>
      </ScrollView>
    );
  }
}

Screenshot:

screenshot


Solution

  • The error implies that 'state' doesn't exist.

    Have you tried changing the method into an arrow function, i.e.

        addTimeDateAppt = () => {...}
    

    This will bind the method to the instance of your component, and references to 'this.state' will work.

    Also you've declared the variable 'self' referring to 'this', but then proceed to use 'this' anyway in the method. Not sure if this is intentional but you shouldn't need it if you use the arrow syntax.