I'm using Vue 2 (class syntax) and Typescript (TSX syntax) -- but if you aren't familiar with TSX in Vue, answer in regular ts/js syntax and I'll apply it to TSX as long as it's also Vue's class syntax -- and I know this question has been asked a few times but none of the answers I've seen have applied to my own situation.
I've created an object array where each object has a name
and a boolean
. I'm outputting these objects as the company I work for's custom HTML elements, let's call them ZChips
(basically act like pretty but dumb radio selects). A ZChip
takes the property 'selected
' as a boolean
on, you guessed it, whether or not it's selected.
The array is called registerCategory
and each object in the array has a name
(basically just its text) and a boolean
i called is_selected
whose default is false
.
Alright, here's how I've outputted my Array (reminder this is TSX syntax and output works fine)
{this.registerCategory.map((field, index) => (
<ZChip
position={'start'}
id = {'field-' index}
value={field}
selected={this.registerCategory[index].is_selected}
onClick={this.onCategorySelect(index)}
>
{this.$t(this.registerCategory[index].name)}
</ZChip>
))}
This outputs all the elements wonderfully. My issue now is getting them to be selected on click.
I've made this function in a separate registration.mixin.ts
file (which is also the same place the array is defined in a computed
block):
methods: {
onCategorySelect(index: number): void {
this.registerCategory[index].is_selected = true;
},
}
This should change the is_select
as only the selected element's selected boolean
. However, that gave me:
[Vue warn]: Invalid handler for event "click": got undefined
When I change void
in onCategorySelect
to boolean
and instead return
the result, the undefined
warning goes away but instead gives me:
[Vue warn]: Error in v-on handler: "TypeError: handler.apply is not a function"
This is apparently because I've changed the value directly. I've tried multiple different ways though (i.e. defined my own in-block boolean and assigned is_selected
to that, etc. but everything I've tried either gives me the same errors or just returns an infinite loop).
And if you're wondering if the Array is at fault -- the same issue occurs when I tried putting them out as separate elements.
I've also tried a simple toggle solution (defining a boolean, toggling its value on click) but that obviously returns ALL the elements as selected once toggled. I know there's a way to bypass that in Vue, I'm just too new it to figure it out.
Any help, solution, or work-around is greatly appreciated. Thanks. :)
CodePudding user response:
Did you figure it out already? I can't test it, but I am pretty sure this works, it matches how indexes are handled in React (afaik):
methods: {
onCategorySelect(index: number): void {
() => this.registerCategory[index].is_selected = true;
},
}
CodePudding user response:
Answering my question in depth in case anyone needs it -- with the help of my supervisor, I've figured out that 2 things were a problem in my code:
I've dumbly put the array in
computed
object (because -- correct me if I'm wrong -- as far as I know Arrays with custom types can't be defined in thedata
object, and anything in acomputed
block can't be mutated. So I moved the array to the same class the rest of my code was (where theZChip
elements are). I'm sure there is some better place to put the Array initialization other than where I put it but oh well.In
onClick
, I had to usearrow function
expression to call the function. This is how the code's been changed:{this.registerCategory.map((field, index) => ( <ZidChip position="start" id = {'field-' index} value={field} selected={this.registerCategory[index].is_selected} onClick={() => this.onCategorySelect(index)} > {this.$t(this.registerCategory[index].name)} </ZidChip> ))}
Where onCategorySelect
looks like:
private onCategorySelect(index: number): void {
this.registerCategory[index].is_selected = !this.registerCategory[index].is_selected;
}