Sort an array of objects against an array of params with a matching value

Context: I have a multiselect dropdown. The user selects multiple object values. Within each object there is a string value that I want to match against. Each multiselect has params assigned. Those params are used later on to sort out the the selection into its own array to send back to the api.

Issue: I have tried to loop through the selections and match against the params. In my case the selection and param will only match up if they happen to be in the same loop at the same time, in other words changing the order of the params changes the result.

I have created a stackblitz that represents the same model of data and logic that is already being used. On the demo there isn’t a dropdown, I have mocked up the response by adding a button to trigger the function with mock data already feeding them. You will see the outputs I am getting with the console.logs()

Expected behaviour:

SELECTION:

  mockSelections = [
    {
      id: "4",
      type: "I_am_BLUE"
    },
    {
      id: "1",
      type: "I_am_RED"
    },
    {
      id: "2",
      type: "I_am_GREEN"
    },
    {
      id: "3",
      type: "I_am_BLUE"
    }
  ];

DESIRED OUTPUT:

  this.filterState = {
      I_am_RED: [
        {
          id: "1",
          type: "I_am_RED"
        }
      ],
      I_am_GREEN: [
        {
          id: "2",
          type: "I_am_GREEN"
        }
      ],
      I_am_BLUE: [
        {
          id: "3",
          type: "I_am_BLUE"
        },
        {
          id: "4",
          type: "I_am_BLUE"
        }
      ]
  };

So basically, the desired output would place all selections with “I_am_BLUE” in the “I_am_BLUE” array, same with greens and greens, reds and reds

FUNCTION:

  handleFilterChange(prop: string, value: any): void {
    let field = this.fields.find(f => f.name === prop);

    if (field.params) {
      console.log("FIELD PARAMS", field.params);
      console.log("SELECTED VALUES", value);
      field.params.forEach((param, i) => {
        // some sort of double looping logic needed here?
        if (value[i].type === param) {
          this.setFilterState(param, value[i], field);
        }
      });
    } else {
      this.setFilterState(prop, value, field);
    }
    console.log("SUBMITTED SORTED VALUES", this.filterState);
  }

StackBlitz examplehttps://stackblitz.com/edit/ngx-select-dropdown-acntzk?file=app%2Fapp.component.ts

Answer

try with these changes:

  handleFilterChange(prop: string, value: any): void {
    let field = this.fields.find(f => f.name === prop);
    for (const [key, value] of Object.entries(this.filterState))
      value.splice(0);
    if (field.params) {
      console.log("FIELD PARAMS", field.params);
      console.log("SELECTED VALUES", value);
      value.forEach(v => this.setFilterState(v.type, v, field));
    } else {
      this.setFilterState(prop, value, field);
    }
    console.log("SUBMITTED SORTED VALUES", this.filterState);
  }

  setFilterState(prop: string, value: any, field: Field): void {
    if (field.name === "multiselect_1") {
      this.filterState[prop].push(value);
    } else {
      //There will be more logic here
      this.filterState[prop] = value;
    }
  }

Leave a Reply

Your email address will not be published. Required fields are marked *