Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

eggplantSword's avatar

Computed set and get a filtered list

I'm trying to separate an array into two draggables because they can't mix between them but still need to be in the same array, basically I need to make sure that depending on a value in the object some always are at the end. The approach I'm trying now is two computed properties that have the first and second rows but the issue is since I'm using with draggable the setter gives me an error.

This is my computed

first_rows: {
		get: function () {
				const ids = this.column_types.filter(x => ['answer', 'points', 'relation'].includes(x.name)).map(x => x.id)
                return this.sheet.survey_excel_columns.filter(x => !ids.includes(x.survey_excel_column_type_id))
            },
            set: function (newValue) {
                const ids = this.column_types.filter(x => ['answer', 'points', 'relation'].includes(x.name)).map(x => x.id)
                const vals = this.sheet.survey_excel_columns.filter(x => !ids.includes(x.survey_excel_column_type_id))

                const ordered_ids = newValue.map(x => x.key)
                console.log(newValue, ordered_ids)
                // this.first_rows = newValue //I tried this but got some error: Maximum call stack size exceeded error
            }
        },

I'm not sure but I think if I'm able to sort by ordered_ids and set that to vals it might work but I'm not sure how to sort that way. How can I make the setter work correctly?

0 likes
2 replies
LaryAI's avatar
Level 58

The issue with the current implementation is that the setter is trying to set the value of the computed property itself, which leads to an infinite loop and eventually a "Maximum call stack size exceeded" error.

To fix this, we can create a separate data property to hold the filtered list, and update it in the setter of the computed property. Here's an example implementation:

data() {
  return {
    filteredList: [],
  };
},
computed: {
  first_rows: {
    get() {
      const ids = this.column_types.filter(x => ['answer', 'points', 'relation'].includes(x.name)).map(x => x.id);
      return this.sheet.survey_excel_columns.filter(x => !ids.includes(x.survey_excel_column_type_id));
    },
    set(newValue) {
      const orderedIds = newValue.map(x => x.key);
      this.filteredList = this.sheet.survey_excel_columns.filter(x => !ids.includes(x.survey_excel_column_type_id)).sort((a, b) => {
        const aIndex = orderedIds.indexOf(a.key);
        const bIndex = orderedIds.indexOf(b.key);
        return aIndex - bIndex;
      });
    },
  },
},

In this implementation, we create a new data property called filteredList to hold the filtered list. In the setter of the first_rows computed property, we sort the original list based on the order of the keys in newValue, and update filteredList with the sorted list.

Note that we also renamed ordered_ids to orderedIds to follow JavaScript naming conventions.

eggplantSword's avatar

@LaryAI what about for the second_rows, I tried what you said changing the filteredList accordingly but it doesn't work when reordering the second rows the ones that get sorted are the first_rows.

second_rows: {
            get() {
                const ids = this.column_types.filter(x => ['answer', 'points', 'relation'].includes(x.name)).map(x => x.id)
                return this.sheet.survey_excel_columns.filter(x => ids.includes(x.survey_excel_column_type_id))
            },
            set(newValue) {
                const orderedIds = newValue.map(x => x.key);
                const ids = this.column_types.filter(x => ['answer', 'points', 'relation'].includes(x.name)).map(x => x.id);
                this.filteredList = this.sheet.survey_excel_columns.filter(x => ids.includes(x.survey_excel_column_type_id)).sort((a, b) => {
                    const aIndex = orderedIds.indexOf(a.key);
                    const bIndex = orderedIds.indexOf(b.key);
                    return aIndex - bIndex;
                });
            },
        },

Please or to participate in this conversation.