Home > Net >  How to use Axios with Vue 3 Composition API
How to use Axios with Vue 3 Composition API

Time:03-11

I am attempting to build a Pokemon filtered search app with Vue 3 and Composition API based on the following tutorial: https://www.youtube.com/watch?v=QJhqr7jqxVo. (GitHub: https://github.com/ErikCH/PokemonVue)

The fetch method used in the search component includes a reduce() function to handle urlIdLookup based on a specific id assigned to each Pokemon in the API response:

    const state = reactive({
      pokemons: [],
      filteredPokemon: computed(()=> updatePokemon()), 
      text: "",
      urlIdLookup: {}
      
    });

    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 }
        ,{})
        console.log('url',state.urlIdLookup 1)
        
      });

urlIdLookup is then passed into the route used to display selected Pokemon info:

    <div
      
      v-for="(pokemon, idx) in filteredPokemon"
      :key="idx"
    >
      <router-link :to="`/about/${urlIdLookup[pokemon.name]}`">
        {{ pokemon.name }}
      </router-link>
    </div>

Instead of using the above fetch setup, I wish to use Axios to handle the request and response from the Pokemon API. After installing Axios in the project and importing it into the component, I added a new fetchPokemon method:

    const fetchPokemon = () => {
      axios.get('https://pokeapi.co/api/v2/pokemon?offset=0')
      .then(response => {
        state.pokemons = response.data
      })
    }

    onMounted(() => {
      fetchPokemon()
    })

While using Axios in this new fetch method, I want to handle urlIdLookup similar to the previous fetch setup, but without using the reduce() method and de-structured accumulator, if possible. How can I go about using Axios to retrieve the urlId of each Pokemon, then pass that urlId into the "about" route in the template?

Here is the full component:

<template>
<div >
<input placeholder="Enter Pokemon here" type="text" 
     v-model="text" />

</div>

  <div >

    
    <div
      
      v-for="(pokemon, idx) in filteredPokemon"
      :key="idx"
    >
      <router-link :to="`/about/${urlIdLookup[pokemon.name]}`">
        {{ pokemon.name }}
      </router-link>
    </div>
  </div>
</template>

<script>
import axios from 'axios';
import { reactive, toRefs, computed, onMounted } from "vue";
export default {
  setup() {
    const state = reactive({
      pokemons: [],
      filteredPokemon: computed(()=> updatePokemon()), 
      text: "",
      urlIdLookup: {}
      
    });

    const fetchPokemon = () => {
      axios.get('https://pokeapi.co/api/v2/pokemon?offset=0')
      .then(response => {
        state.pokemons = response.data
      })
    }

    onMounted(() => {
      fetchPokemon()
    })

    // 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 }
    //     ,{})
    //     console.log('url',state.urlIdLookup 1)
        
    //   });

    function updatePokemon(){
      if(!state.text){
        return [] 
      }
      return state.pokemons.filter((pokemon)=> 
          pokemon.name.includes(state.text)
      )
    }

    return { ...toRefs(state), fetchPokemon, updatePokemon };
  }
};
</script>

CodePudding user response:

it seem id is not necessary, why not use name be id. if you want use interger be must, you can foreach results set index be id to each item, then

 <router-link :to="`/about/${pokemon.id}`">
        {{ pokemon.name }}
      </router-link>

CodePudding user response:

If you just want to replace reduce you can use for loop:

const results = [{"name":"bulbasaur","url":"https://pokeapi.co/api/v2/pokemon/1/"},{"name":"ivysaur","url":"https://pokeapi.co/api/v2/pokemon/2/"},{"name":"venusaur","url":"https://pokeapi.co/api/v2/pokemon/3/"},{"name":"charmander","url":"https://pokeapi.co/api/v2/pokemon/4/"},{"name":"charmeleon","url":"https://pokeapi.co/api/v2/pokemon/5/"},{"name":"charizard","url":"https://pokeapi.co/api/v2/pokemon/6/"},{"name":"squirtle","url":"https://pokeapi.co/api/v2/pokemon/7/"},{"name":"wartortle","url":"https://pokeapi.co/api/v2/pokemon/8/"},{"name":"blastoise","url":"https://pokeapi.co/api/v2/pokemon/9/"},{"name":"caterpie","url":"https://pokeapi.co/api/v2/pokemon/10/"},{"name":"metapod","url":"https://pokeapi.co/api/v2/pokemon/11/"},{"name":"butterfree","url":"https://pokeapi.co/api/v2/pokemon/12/"},{"name":"weedle","url":"https://pokeapi.co/api/v2/pokemon/13/"},{"name":"kakuna","url":"https://pokeapi.co/api/v2/pokemon/14/"},{"name":"beedrill","url":"https://pokeapi.co/api/v2/pokemon/15/"},{"name":"pidgey","url":"https://pokeapi.co/api/v2/pokemon/16/"},{"name":"pidgeotto","url":"https://pokeapi.co/api/v2/pokemon/17/"},{"name":"pidgeot","url":"https://pokeapi.co/api/v2/pokemon/18/"},{"name":"rattata","url":"https://pokeapi.co/api/v2/pokemon/19/"},{"name":"raticate","url":"https://pokeapi.co/api/v2/pokemon/20/"}]

const res = results.reduce((acc, cur, idx)=> 
    acc = {...acc, [cur.name]:idx 1 }
,{})
const res2 = {}
for(let i = 0; i < results.length; i  ) {
  res2[results[i].name] = i   1
}
console.log('with reduce',res)
console.log('with for loop',res2)

  • Related