Search code examples
javascriptreactjsfilterarrow-functions

Expected to return a value at the end of arrow function array-callback-return on filter function


I'm working in React and I'm currently getting the error "Expected to return a value at the end of arrow function array-callback-return". I've searched other questions, but can't seem to find one that matches min (unless I'm totally blind). I have the following code.

const self = this;
const relevantCompanyMeasures = this.props.companyMeasures
  .filter(companyMeasure => {
    for(const measure of self.state.measures) {
      if(measure.id === companyMeasure.measure_type_id) return true;
      else return false;
    }
  });

The code loops through two arrays of objects looking for a match between the two. If I had only returned true for matches, I would have understood the error. However, I return false in the case that there is no match. As a result, I'm struggling to see how I'd end up in a situation where there is no return value at the end of the arrow function.


Solution

  • That is because the return only exits the for loop, and not the entire callback in Array.prototype.filter(). Instead of using for loop to check if companyMeasure.measure_type_id exists in self.state.measures, you can simply do an array map, which returns all the IDs, and then check against that return array if the ID exists using Array.prototype.includes:

    const self = this;
    const relevantCompanyMeasures = this.props.companyMeasures
      .filter(companyMeasure => {
        return self.state.measures.map(m => m.id).includes(companyMeasure.measure_type_id);
      });
    

    Even better:

    • since you are using arrow functions, the lexical this from the enclosing scope is preserved, so you don't even need to proxy this at all
    • you can also create the array map outside the .filter() callback to reduce overhead
    • now the .filter() callback is a one-liner, we can get rid of the curly brackets and take advantage of implicit returns in arrow functions

    Here's how the final code should look like:

    const ids = this.state.measures.map(m => m.id);
    const relevantCompanyMeasures = this.props.companyMeasures
      .filter(companyMeasure => id.includes(companyMeasure.measure_type_id));