Using Nuxt 2.14.12, trying to display a dictionary using the V-FOR directive. The Code snippet below shows code trying to display the dictionary pokiAbilities. The code segment with the V-For is not being rendered and I don't know why.
<template>
<div>
<div class="max-w-sm rounded-sm overflow-hidden shadow-lg m-16">
<div lass="mx-6 my-4 border-b border-gray-light content-center">
<div class="font-extrabold text-2xl text-gray-darker mb-4 text-center">abilities</div>
</div>
<div v-for="(value, index) in pokiAbilities" :key="index">
<div class="mx-6 my-4 border-b border-gray-light">
<div class="font-semibold text-gray-dark text-sm mb-2">
<ul class="list-inside bg-rose-200">
<li><p>{{ index }}</p></li>
<li><p> Effect: </p><p class="text-blue-300 font-black">{{ value.effect }}</p></li>
<li><p> Short Effect: </p><p class="text-blue-300 font-black">{{ value.short_effect }}</p></li>
</ul>
</div>
</div>
<div class="mx-6 my-4 flex">
<div class="flex-grow">
<span class="inline-block bg-red-light rounded-full p-1 pb-0 mr-2">
<svg fill="white" width="16" height="16" viewBox="0 0 24 24">
<path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M11,16.5L18,9.5L16.59,8.09L11,13.67L7.91,10.59L6.5,12L11,16.5Z"></path>
</svg>
</span>
</div>
</div>
</div>
</div>
</div>
</template>
Picture of result below
Example of pokiAbilities dictionary below
{
"static":{"effect":"destroy opponent", "language":{"name":"en"},"short_effect":"get dazzled"},
"lightning-rod":{"effect":"deal 100 dmg", "language":{"name":"en"},"short_effect":"freeze enermy"}
}
The pokiAbilities is constructed from calling 2 API end points, then after manipulating the JSON data to construct pokiAbilities. Code below
<script>
export default {
props: {
pokemon: Object
},
data() {
return {
pokiAbilities: this.getPokemonAbilities(),
}
},
methods: {
async getPokemonAbilities(){
let abilitiesList = this.getPokemonAbilitiesNames()
let abilities = {}
for (let i = 0; i < abilitiesList.length; i++) {
let abi = await this.$axios.$get('https://pokeapi.co/api/v2/ability/'+abilitiesList[i])
abilities[abilitiesList[i]] = this.getAbilityEn(abi)
}
console.log(abilities)
return abilities
},
getPokemonAbilitiesNames(){
let abilities = []
for (let i = 0; i < this.pokemon.abilities.length; i++) {
abilities[i] = this.pokemon.abilities[i].ability.name
}
return abilities
},
getAbilityEn(abi){
let enAbi = {}
abi.effect_entries.forEach(langAbi => {
if(langAbi.language.name === 'en'){
enAbi = langAbi
}
});
return enAbi
}
},
}
</script>
The first API call is done in the parent component and the result (names of abilities) is passed down in the Pokemon prop. The second API call is done in this component to retrieve abilities based on the first API call. I then combine the two results to get the names and descriptions of those abilities.
Explanation of each method
getPokemonAbilitiesNames() ---> gets the names of abilities of pokemon on from the Pokemon prop and returns a list of those names.
getAbilityEn(abi) ---> takes results of second call API (used in the getPokemonAbilities() method) and makes sure that the abilities are in English.
getPokemonAbilities() ---> Takes the result of getAbility(abi) and getPokemonAbilitiesNames(), combines into a dictionary as Names as Key and abilities as Values.
THings I have tried
In order to run the getPokemonAbilities() method to initialize pokiAbilities so that it can be passed to the V-For directive, the method needed to be run within an async method. My solution was to initialize the data within an async created()
data() {
return {
pokiAbilities: null
}
},
async created() {
this.pokiAbilities = await this.getPokemonAbilities()
},
I am not entirely convinced that this is the proper way of doing it but it worked.