Reacting
Reacting

Reputation: 6123

Array method error: TypeError: Cannot read property 'filter' of undefined

So, I am trying to remove some elements from an array. I have 2 filters which I need to call. One is for filtering data with a search box and the other depending on a condition. But I am getting this error:

TypeError: TypeError: Cannot read property 'filter' of undefined

This is the component:

const PassengerCardBasedOnRoute = ({
  searchParam,
  passengerCardId,
  isAddToMyPassengersSuccess,
  unassignedDropOffPassengers,
}) => {

  // This is the filter that work based on a search parameter
  const filteredData = filterByParam =>
    filterByParam.filter(obj =>
      Object.keys(obj).some(key =>
        String(obj[key])
          .toLowerCase()
          .includes(searchParam.toLowerCase()),
      ),
    );

  // Here is where I need to remove from the array the condition met
  const filterByPassengerCardId = passengersData => {
    remove(passengersData, info => {
      return info.id === passengerCardId;
    });
  };

  const componentToRenderBasedOnParams = info => (
    <View key={info.id}>
      {isAddToMyPassengersSuccess && info.id === passengerCardId && (
        <PassengersAdded name={info.name} id={info.id} />
      )}
      <PassengersInfo
        id={info.id}
        name={info.name}
        searchParam={searchParam}
      />
    </View>
  );

  const showFeedbackIfNoLength = data => {
    if (!passengerCardId && size(filteredData(data))) {
      filteredData(data).map(info => componentToRenderBasedOnParams(info));
    } else if (passengerCardId) {

      // HERE IS WHERE THE APP THROWS THE ERROR
      filteredData(filterByPassengerCardId(data)).map(info =>
        componentToRenderBasedOnParams(info),
      );

    } else {
      return <EmptyState>No records found</EmptyState>;
    }

    return data;
  };

  return (
    <>
      <OptionsModal>{<AllPassengersOptionsModal />}</OptionsModal>
      <View>
        {!navigationStore.index && unassignedDropOffPassengers
          ? showFeedbackIfNoLength(unassignedDropOffPassengers)
          : null}
      </View>
    </>
  );
};

EDIT

And here comes the error:

  const filteredData = filterByParam =>
    // Here comes the error
    filterByParam.filter(obj =>
      Object.keys(obj).some(key =>
        String(obj[key])
          .toLowerCase()
          .includes(searchParam.toLowerCase()),
      ),
    );

When this condition is met:

      // HERE IS WHERE THE APP THROWS THE ERROR
      filteredData(filterByPassengerCardId(data)).map(info =>
        componentToRenderBasedOnParams(info),
      );

When this other condition is met, everything works properly:

   if (!passengerCardId && size(filteredData(data))) {
      filteredData(data).map(info => componentToRenderBasedOnParams(info));
    }

What am I missing to achieve what I need?

Upvotes: 2

Views: 1608

Answers (2)

nick
nick

Reputation: 489

The problems could come from here:

  // Here is where I need to remove from the array the condition met
  const filterByPassengerCardId = passengersData => {
    remove(passengersData, info => {
      return info.id === passengerCardId;
    });
  };

Maybe it is not working in a way you are expecting, at least it is not returning anything (returns undefined). While you may expect an array return from this function.

Upvotes: 1

Scott Rudiger
Scott Rudiger

Reputation: 1300

It looks like in the expression filteredData(filterByPassengerCardId(data)), filteredData is expecting an Array; however, filterByPassengerCardId(data) returns undefined.

Change filterByPassengerCardId's return value to an Array and the error should no longer be thrown.

Edit: Saw your comment that you're using Lodash's remove method which does, in fact, return an Array.

In that case just edit filterByPassengerCardId to return the result of calling remove:

const filterByPassengerCardId = passengersData => {
  return remove(passengersData, info => {
    return info.id === passengerCardId;
  });
};

Edit: Or better yet, for conciseness:

const filterByPassengerCardId = passengersData => (
  remove(passengersData, ({id}) => id === passengerCardId)
);

Upvotes: 2

Related Questions