Search code examples
vue.jsaxiosnuxt.jsinfo

$route.params.id dont want to give id data when clicking on drink. CocktailDB API, nuxt.js


Hello Im doing a simple cocktailapp to practice nuxt.js and axios with coktailDB API https://www.thecocktaildb.com/api.php. In drinks/index.vue I have listed all drinks with v-for. When clicking on a drink you get to drinks/_id/index.vue page where the full info about the drink will get showed by its ID. Im using $route.params.id and I have tried with this.$route.params.id. No drink info get showed. Its just shows undefined and brackets. How can I get the drink info to be showed by its ID after been clicking on a specific drink? Thanks in advance!

Drinks/index.vue;

<template>
  <div>
  <div>
    <SearchDrink/>
  </div>
  <div>
  <div v-for="drink in drinks" :key="drink.id"> 
  <nuxt-link :to="'drinks/' + id">
    <div class="drink">
    <p> {{ drink.strDrink
    }} </p>
    <img :src="drink.strDrinkThumb" alt=""/> 
    <p>Instructions:</p>
    <p> {{ drink.strInstructions }} </p>
    <div class="ing"> Ingridients: 
      <ul>
        <li>{{ drink.strIngredient1 }} </li>
        <li>{{ drink.strIngredient2 }} </li>
        <li>{{ drink.strIngredient3 }} </li>
        <li>{{ drink.strIngredient4 }} </li>
        <li>{{ drink.strIngredient5 }} </li>
      </ul>
  </div>
  </div>
</nuxt-link>
</div>
</div>
</div>
</template>

<script>
import SearchDrink from '../../components/SearchDrink.vue'
import axios from 'axios'

export default {
  components:{
    SearchDrink,
  },
  data(){
    return {
      drinks: [],
    }
  },
 methods: {
    getAllDrinks(){
      axios.get('https://thecocktaildb.com/api/json/v1/1/search.php?s=')
      .then((response) => {
        this.drinks = response.data.drinks
        const myDrink = response.data.drinks
        console.log(myDrink)
        console.log(myDrink.strDrinkThumb)  
        })
    .catch((error) =>{
      console.log(error)
    })
    
    }, 
 },
  created(){
    this.getAllDrinks()
  },
  // methods: {
  //   searchDrink(){
  //     if(!this.search){
  //       return this.drinks
  //     }else{
  //       return this.drinks.filter(drink => 
  //       drink.text.toLowerCase().includes(this.search.
  //       toLowerCase()))
  //     }
  //   }
  // },
    head(){
        return {
            title: 'Drinks App',
            meta: [
                {
                    hid: 'description',
                    name: 'description',
                    content: 'Best place to search a Drink'
                }
            ]
        }
    }
}
</script>

Drinks/_id/index.vue;

<template>
  <div>
    <nuxt-link to="/drinks">
        Go Back
    </nuxt-link>
    <h2> {{ drink }} </h2>
    <hr>
    <small>Drink ID: {{ this.$route.params.id }}</small>
  </div>
</template>

<script>
import axios from 'axios'

export default {
    data(){
        return{
            drink: {}
        }
    },
    methods: {
    getAllDrinks(){
      axios.get(`www.thecocktaildb.com/api/json/v1/1/lookup.php?i=${this.$route.params.id}`)
      .then((response) => {
        this.drinks = response.data.drinks
        const myDrink = response.data.drinks
        console.log(myDrink) 
        })
    .catch((error) =>{
      console.log(error)
    })
    
    }, 
 },
  created(){
    this.getAllDrinks()
  },
  head(){
        return {
            title: this.drink,
            meta: [
                {
                    hid: 'description',
                    name: 'description',
                    content: 'Best place to search a Drink'
                }
            ]
        }
    }
}
</script>

enter image description here

enter image description here


Solution

  • There are quite a few things that be improved here (and the API is a bit messy too).
    Here is how I would do it with modern practices.

    /pages/drinks/index.vue

    <template>
      <div>
        <div v-for="drink in drinks" :key="drink.idDrink">
          <nuxt-link :to="`/drinks/${drink.idDrink}`">
            <div class="drink">
              <p>{{ drink.strDrink }}</p>
              <img width="100px" height="100px" :src="drink.strDrinkThumb" alt="" />
              <p>Instructions:</p>
              <p>{{ drink.strInstructions }}</p>
              <div class="ing">
                <p>Ingredients:</p>
                <ul>
                  <li>{{ drink.strIngredient1 }}</li>
                  <li>{{ drink.strIngredient2 }}</li>
                  <li>{{ drink.strIngredient3 }}</li>
                  <li>{{ drink.strIngredient4 }}</li>
                  <li>{{ drink.strIngredient5 }}</li>
                </ul>
              </div>
            </div>
          </nuxt-link>
        </div>
      </div>
    </template>
    
    <script>
    import axios from 'axios'
    
    export default {
      data() {
        return {
          drinks: [],
        }
      },
      async fetch() {
        await this.getAllDrinks()
      },
      methods: {
        async getAllDrinks() {
          try {
            const { data } = await axios.get(
              'https://thecocktaildb.com/api/json/v1/1/search.php?s='
            )
            this.drinks = data.drinks
          } catch (error) {
            console.log('error', error)
          }
        },
      },
    }
    </script>
    

    /pages/drinks/_id.vue

    <template>
      <div>
        <nuxt-link to="/drinks"> Go Back </nuxt-link>
        <h2>{{ drink.strGlass }}</h2>
        <hr />
        <small>Drink ID: {{ $route.params.id }}</small>
      </div>
    </template>
    
    <script>
    import axios from 'axios'
    
    export default {
      data() {
        return {
          drink: {},
        }
      },
      async fetch() {
        await this.getAllDrinks()
      },
      methods: {
        async getAllDrinks() {
          try {
            const { data } = await axios.get(
              `https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i=${this.$route.params.id}`
            )
            this.drink = data.drinks[0]
          } catch (error) {
            console.log('error', error)
          }
        },
      },
    }
    </script>
    

    Few notes:

    • I skipped the parts I don't have access to (like your SearchDrink component) or that are not relevant with the current issue
    • you probably would need to use the axios module
    • you don't need to import your Nuxt components, it is done for you