0

I am working on a project where I have a workout list as well as a filter to view a specific selection of the workouts depending on which checkboxes are marked. So far, everything has been working well thanks to a technique solved here . This technique works great for filtering for individual items, however, when I nest items within the array it no longer works.

Currently, I have a workout model that takes in the following:

title,
description,
imagePath,
type: string,
duration,
specialty,
phase,
zwo

And I have checkboxes using Angular SelectionModel. These checkboxes are filtering for the following: phase, specialty, and type using the filter method provided in the link above (this is working as expected):

filterWorkouts(phases: string[], specialties: string[], types: string[]) {
  const workouts = this.workouts.filter(workout => {
    return (
      (phases.length === 0 || phases.indexOf(workout.phase) >= 0) &&
      (specialties.length === 0 || specialties.indexOf(workout.specialty) >= 0) &&
      (types.length === 0 || types.indexOf(workout.type) >= 0)
    );
  });
  this.selectedWorkouts.next(workouts);
}

I decided there may be cases where I want multiple phases. To prepare for this, I created a nested array within the service (in the StackBlitz this can be found in features/workouts-page/workoutservice/workout.service). This nested array takes in the same items from the workout model, with the exception that the phase is a nested array:

 workouts: Workout[] = [
    new Workout(
      'title',
      `description...`,
      "..img",
      "type",
      duration,
      "specialty...",
      ["Base 1", "Testing"],
      true/false
    ),

Note the ["Base 1", "Testing"] as this is now a nested array.

The problem is, the filtering method breaks when I make this change. The only way the checkbox filter works is if no phase is selected. If I go to the filterWorkouts() from above, and in the return change the line:

... (phases.length === 0 || phases.indexOf(workout.phase) >= 0) && ...

to: ... (phases.length === 0 || phases.indexOf(workout.phase[0]) >= 0) && ...

It works again, but of course only looks for the array with the index of 0.

I have tried looping through the array and checking the index against the filter, but this has broken my app every time.

Is there a way to filter my checkboxes against every item in the array rather than only one? So if the phase of a workout has ["Base 1", "Race"] I want it to appear whether Base 1 or Race is checked in the boxes.

Any help would be greatly appreciated. I am happy to clarify anything as well.

Here is the StackBlitz (simplified for ease of use). The service location is mentioned above. The workouts-filter and workouts-list are coming from two separate components within the workouts-page folder.

2
  • Try: !phases.length || phases.some(phase => workout.phase.includes(phase)). This condition will be true if phases is empty or workout.phase contains any of its elements. I'm not sure if that is the logic you're looking for. Commented Feb 14, 2020 at 1:11
  • Titus, this was perfect and seems to be working great. Thank you so much!! Feel free to put this as the answer if you so desire so I can accept it and so you can get reputation. Thanks again, I really appreciate it Commented Feb 14, 2020 at 1:22

1 Answer 1

2

You can use a condition like this:

!phases.length || phases.some(phase => workout.phase.includes(phase))

What this does is to first check if the phases array is empty and if it is not, check if any of its elements is present in the workout.phase array.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.