How can i set a valid primitive Key for my v-for cycle?
i need to show in a data table a v-dialog that contains basically a restaurant menu structured as an array of objects of arrays of object. That is how i already structured my menu:
menu_ristorante: [ { primi: [ { nome_portata: "Fettuccine al ragù", quantita_portata: 0 }, { nome_portata: "Tagliatelle alla boscaiola", quantita_portata: 0 }, { nome_portata: "Spaghetti allo scoglio", quantita_portata: 0 }, { nome_portata: "Zuppa di ceci", quantita_portata: 0 }, { nome_portata: "Fettuccine al ragù", quantita_portata: 0 } ] }, { secondi: [{ nome_portata: "Vitello tonnato", quantita_portata: 0 }] }, { contorni: [{ nome_portata: "Insalata mista", quantita_portata: 0 }] }, { bibite: [ { nome_portata: "Acqua", quantita_portata: 0 }, { nome_portata: "Vino Rosso", quantita_portata: 0 }, { nome_portata: "Vino Bianco", quantita_portata: 0 }, { nome_portata: "Caffè", quantita_portata: 0 } ] } ],
Then i have inserted my dialog inside a v-data-table that should be triggered by the click of the property item.nome that is the firs column of my table
<v-data-table light :headers="headers_tabella_persone" :items="tabella_persone" :items-per-page="10" class="elevation-1" > <template v-slot:item.interno="{ item }"> <v-checkbox v-model="item.interno"></v-checkbox> </template> <template v-slot:item.nome="{ item }" @click="dialog_visualizza_menu=true"> <v-dialog v-model="dialog_visualizza_menu" scrollable max-width="300px"> {{item}} <v-card> <v-card-title>Seleziona primo</v-card-title> <v-divider></v-divider> <v-card-text style="height: 300px;"> <v-radio-group v-model="dialogm1" column> <v-radio v-for="portata in menu_ristorante" :key="portata.primi"></v-radio> </v-radio-group> </v-card-text> <v-divider></v-divider> <v-card-title>Seleziona secondo</v-card-title> <v-divider></v-divider> <v-card-text style="height: 300px;"> <v-radio-group v-model="dialogm1" column> <v-radio v-for="portata in menu_ristorante" :key="portata.secondi"></v-radio> </v-radio-group> </v-card-text> <v-card-title>Seleziona bibite</v-card-title> <v-divider></v-divider> <v-card-text style="height: 300px;"> <v-radio-group v-model="dialogm1" column> <v-radio v-for="portata in menu_ristorante" :key="portata.bibite"></v-radio> </v-radio-group> </v-card-text> <v-card-actions> <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Close</v-btn> <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Save</v-btn> </v-card-actions> </v-card> </v-dialog> </template> </v-data-table>
But i receive this error on the key in return
Avoid using non-primitive value as key, use string/number value instead.
So my entire column item.nome won’t be visible. How can i set a valid primitive key referenced to the stucture of my menu?
EDIT-1 i solved the problem of the key by removing the initial array level from my object and that is my updated object
menu_ristorante: { primi: [ { id: 1, nome_portata: "Fettuccine al ragù", quantita_portata: 0 }, { id: 2, nome_portata: "Tagliatelle alla boscaiola", quantita_portata: 0 }, { id: 3, nome_portata: "Spaghetti allo scoglio", quantita_portata: 0 }, { id: 4, nome_portata: "Zuppa di ceci", quantita_portata: 0 }, { id: 5, nome_portata: "Fettuccine al ragù", quantita_portata: 0 } ], secondi: [ { id: 1, nome_portata: "Vitello tonnato", quantita_portata: 0 } ], contorni: [ { id: 1, nome_portata: "Insalata mista", quantita_portata: 0 } ], bibite: [ { id: 1, nome_portata: "Acqua", quantita_portata: 0 }, { id: 2, nome_portata: "Vino Rosso", quantita_portata: 0 }, { id: 3, nome_portata: "Vino Bianco", quantita_portata: 0 }, { id: 4, nome_portata: "Caffè", quantita_portata: 0 } ] },
The template is the same
<template v-slot:item.nome="{ item }"> <div style="cursor:pointer;" @click="popolaMenu()">{{item.nome}}</div> </template> </v-data-table> </v-tab-item> <v-dialog v-model="dialog_visualizza_menu" scrollable max-width="800px"> <v-card> <v-card-title>Seleziona primo</v-card-title> <v-divider></v-divider> <v-card-text style="height: 800px;"> <v-radio-group v-model="dialogm1" column> <v-radio v-for="(portata) in menu_ristorante" :key="portata.primi">{{portata.primi}}</v-radio> </v-radio-group> </v-card-text> <v-divider></v-divider> <v-card-title>Seleziona secondo</v-card-title> <v-divider></v-divider> <v-card-text style="height: 800px;"> <v-radio-group v-model="dialogm1" column> <v-radio v-for="(portata) in menu_ristorante" :key="portata.secondi">{{portata.secondi}}</v-radio> </v-radio-group> </v-card-text> <v-card-title>Seleziona bibite</v-card-title> <v-divider></v-divider> <v-card-text style="height: 800px;"> <v-radio-group v-model="dialogm1" column> <v-radio v-for="portata in menu_ristorante" :key="portata.bibite">{{portata.bibite}}</v-radio> </v-radio-group> </v-card-text> <v-card-actions> <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Close</v-btn> <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Save</v-btn> </v-card-actions> </v-card> </v-dialog>
I have only put it outsite of the v-data-table to avoid recursive call that will cause crash of my app, so now if i click on a name the pop up is shown but it is populated in the wrong way
You are using an object as a key, that’s why you get that error.
One fast fix would be to change the loop like this:
v-for="(portata, index) in menu_ristorante" :key="index"
but, the best would be for you to add a unique ID (string or integer) to each of the iterate objects and use it as key.
Buon appetito 😉
You have to add a key for the loop items in either number
or string
. But you are adding a object
.
I would suggest you to have an id in the object inside menu_ristorante
.
Also, you can use the index as key like below.
v-for="portata, index in menu_ristorante" :key="index"
The above is not suggested in every place as it doesn’t allow vue to exactly find which element child is changed.