Selector is depending on other selectors and is not working now when being called

Viewed 38

I have an issue with Redux Toolkit.
I have several Selectors that select the tasks the way I want them. I also have a sort and filter functionality, so it returns the sorted and filtered version. I will try to break it down as much as I can to make sense of what I am expecting.

Code

export const {
  selectAll: selectAllTasks,
} = tasksAdapter.getSelectors((state) => state.tasks);

I have this selector created by the Adapter selectAllTasks. This selector is used by other selectors.


export const selectSortedTasks = createSelector(
  [
    selectAllTasks,
    (state) => ({
      sorting: state.tasks.sorting,
      checklist: selectAllChecklist(state),
    }),
  ],
  (tasks, { sorting, checklist }) => {
    switch (sorting.type) {
      case 'checklist':
        return tasks.sort((a, b) => {
          const checklist1 = checklist.filter((item) => item.taskId === a.id);
          const checklist2 = checklist.filter((item) => item.taskId === b.id);
          return checklist2.length - checklist1.length;
        });

      case 'date':
        return tasks.sort((a, b) => {
          const date1 = parseDateTimeString(a.dueDate);
          const date2 = parseDateTimeString(b.dueDate);
          return compareAsc(date1, date2);
        });

      case 'priority':
        return tasks.sort((a, b) => {
          const priority1 = priorities.find(
            (prio) => prio.name === a.priority
          ).level;
          const priority2 = priorities.find(
            (prio) => prio.name === b.priority
          ).level;
          return priority2 - priority1;
        });

      default:
        return tasks.sort((a, b) => a.order - b.order);
    }
  }
);

This selector sorts the array and is currently used as the default for other selectors.


export const selectTasksByFilter = createSelector(
  [selectSortedTasks, (state) => state.tasks.filter],
  (tasks, filter) => {
    return tasks.filter((task) => {
      switch (filter.type) {
        case 'name':
          return task.name.toLowerCase().includes(filter.value.toLowerCase());

        case 'date':
          return checkDueDate(task.dueDate) === filter.value;

        default:
          return true;
      }
    });
  }
);

This selector filters the sorted array. You can see I am using selectSortedTasks as am entry point!


export const selectTaskIdsByStage = createSelector(
  [selectTasksByFilter, (state, stage) => stage.name],
  (tasks, stage) => {
    return tasks.filter((task) => task.stage === stage).map((task) => task.id);
  }
);

Then finally I have this selector, that filters by stage and returns the ID. You can see I am using selectTasksByFilter as my entry point.


Expectations

Now I am calling selectTaskIdsByStage and I get the default sorting. That's fine. In the UI I am changing the sorting to "priority", so the expectation is to get a new sorted array, sorted by priority, highest first. But what actually is happening is nothing. Nothing changes.

Now if I change the function like this

export const selectTaskIdsByStage = createSelector(
- [selectTasksByFilter, (state, stage) => stage.name],
+ [selectSortedTasks, (state, stage) => stage.name],
  (tasks, stage) => {
    return tasks.filter((task) => task.stage === stage).map((task) => task.id);
  }
);

And use selectSortedTasks as my entry point, skipping the filtering process, and I change the sorting to "priority" or something else, then I get a sorted array back.

The issue is I need the filtering step as well. Why is it not working if I use filtering in between? I try switching it up by having the filtering selector being the entry point for the sorting selector, but that didn't change anything about it.

0 Answers
Related