I am building Pokemon filtered search app using Vue 3 with Composition API, based on the following tutorial: https://www.youtube.com/watch?v=QJhqr7jqxVo. The Home view in the app uses a fetch method to fetch Pokemon from the PokemonAPI:
fetch('https://pokeapi.co/api/v2/pokemon?offset=0')
.then((res)=> res.json())
.then((data)=> {
console.log(data)
state.pokemons = data.results;
state.urlIdLookup = data.results.reduce((acc, cur, idx)=>
acc = { ...acc, [cur.name]:idx+1 }
,{})
})
Each Pokemon in the JSON response includes an index number. The second promise uses a reduce method to handle urlIdLookup. urlIdLookup is then passed into the router-link path used to redirect to Pokemon about/details page:
<div class="ml-4 text-2x text-blue-400"
v-for="(pokemon, idx) in filteredPokemon" :key="idx">
<router-link :to="`/about/${urlIdLookup[pokemon.name]}`">
{{ pokemon.name }}
</router-link>
</div>
The tutorial, however, does not explain why it is necessary to create a new accumulator object (“acc”) inside the reduce method, and then deconstruct the accumulator (“…acc”). Could someone perhaps explain why it’s necessary to create that object, then deconstruct it? Also, is there perhaps a better method for retrieving the id and passing it into the router link?
Here is the full component:
<template>
<div class="w-full flex justify-center">
<input type="text" placeholder="Enter Pokemon here"
class="mt-10 p-2 border-blue-500 border-2" v-model="text"/>
</div>
<div class="mt-10 p-4 flex flex-wrap justify-center">
<div class="ml-4 text-2x text-blue-400"
v-for="(pokemon, idx) in filteredPokemon" :key="idx">
<router-link :to="`/about/${urlIdLookup[pokemon.name]}`">
{{ pokemon.name }}
</router-link>
</div>
</div>
</template>
<script>
import { reactive, toRefs, computed } from 'vue';
export default {
name: 'Home',
setup() {
const state = reactive({
pokemons: [],
urlIdLookup:{},
text: "",
filteredPokemon: computed(()=> updatePokemon())
})
const updatePokemon = () => {
if(!state.text) {
return []
}
return state.pokemons.filter((pokemon) =>
pokemon.name.includes(state.text)
)
}
fetch('https://pokeapi.co/api/v2/pokemon?offset=0')
.then((res)=> res.json())
.then((data)=> {
console.log(data)
state.pokemons = data.results;
state.urlIdLookup = data.results.reduce((acc, cur, idx)=>
acc = { ...acc, [cur.name]:idx+1 }
,{})
})
return { ...toRefs(state), updatePokemon }
}
}
</script>