2

I have been researching this topic for a while and am completely stuck. I am using React.js, and using an es6 class component.

When I call this.showDate inside of my filterCourses function it is claiming that it can't read the showDate property of undefined. This means the keyword this is undefined.

I have tried binding this in the constructor.

Question

How do I make this defined?


class Upcoming_Training extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: '',
    }
  }
  componentDidMount() {}
  showDate(date) {
    // Creates a more readable date
    if (date) {
      date = date.substring(0, date.indexOf("T"));
      let dateArr = date.split('-');
      return dateArr[1] + '/' + dateArr[2] + '/' + dateArr[0];
    }
  }
  filterCourses() {
    let courseRows = [];
    if (this.props.upcoming_training != []) {
      if (this.showDate) {
        let courseRows = this.props.upcoming_training.map(function (
          course, index) {
          return <tr>
                   <th><button className='btn btn-sm btn-primary'> More Info </button></th> {/*Will make this button do something later*/}
                   <td>{course.Course}</td>
                   <td> {(course.Name.includes("OL -") ? course.Name.slice(5) : course.Name)}</td>
                   <td>{this.showDate(course.Start)}</td>
                   <td>{this.showDate(course.End)}</td>
                   <td>{(course.IsOnline ? "Online" : "On-Site")}</td>
                 </tr>
        })
      }
      return courseRows;
    }
    return [];
  }
6
  • You've already tried adding this.filterCourses = this.filterCourses.bind(this) to your constructor? Commented May 24, 2018 at 22:11
  • yes I added this.filterCourses = this.filterCourses.bind(this) and this.showDate = this.showDate.bind(this) **I dont really understand what this is doing from a fundamental level, so if doing it to both is a problem then I didnt know. But just doing the this.filterCourses on it's own did not work either. Commented May 24, 2018 at 22:12
  • You only need to bind functions that are using the this keyword. So you would need it in filterCourses, but not in showData, since you never use this in that function. Commented May 24, 2018 at 22:17
  • Thanks for that bit of info Trevor! :) Commented May 24, 2018 at 22:22
  • 1
    Not 100% sure, but I think an issue might be that you are passing a function to this.props.upcoming_training.map, That map as defined in developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… takes a thisArg and since you are not providing one it will be undefined. That causes the this in this.showDate to be undefined. Either binding showDate or providing a thisArg should aleviate the problem.
    – Emil L
    Commented May 24, 2018 at 22:28

2 Answers 2

4

As Emil H mentioned in the comments above, the issue is that this is not bound once you enter the map function. You can either pass the thisArg to the map function, or move that function to a separate class function that you bind in your constructor. That would look something like this (untested):

class Upcoming_Training extends Component {
  constructor(props) {
    super(props);
    this.filterCourses = this.filterCourses.bind(this);
    this.renderCourseRow = this.renderCourseRow.bind(this);
  }

  showDate(date) {
    // Format date...
  }

  renderCourseRow(course, index) {
    return (
      <tr key={index}>
        <th><button className='btn btn-sm btn-primary'> More Info </button></th>
        <td>{course.Course}</td>
        <td>{(course.Name.includes("OL -") ? course.Name.slice(5) : course.Name)}</td>
        <td>{this.showDate(course.Start)}</td>
        <td>{this.showDate(course.End)}</td>
        <td>{(course.IsOnline ? "Online" : "On-Site")}</td>
      </tr>
    )
  }

  filterCourses() {
    if (this.props.upcoming_training != []) {
      return this.props.upcoming_training.map(renderCourseRow);
    }
    return [];
  }

  // ...Rest of component
}
1
  • Arrow function also could have worked. I was so use to writing keyword function due to IE compatibility, but create-react-app allows arrow functions to be converted. Which is awesome. Commented May 24, 2018 at 22:47
-1

First remove comma after inputValue: '', in the this.state declaration. Also in your filterCourses function the if(this.showDate) condition is looking for a showDate property not a function. You function showDate also expects a date.

You also need a render function as any react component is required to have one.

1
  • I have a render function, I just did not put it in the code snippet as it was not relevant to the error. I only added that if condition after the fact that this error started happening, so even without it, the error is there. Commented May 24, 2018 at 22:21

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.