wonder95
wonder95

Reputation: 4255

Make API call based on route parameter in Nuxt 3 dynamic compopnent

I'm attempting to create a simple Nuxt 3 app for learning purposes that uses dynamic routes to load data from an API when the page is loaded. What I'm trying to figure out is how to use the route id param with the composition API to call an external API and make the data available in the component.

So here is my basic folder structure:

/pages
   \
   index.vue
   /currency
        \
        [id].vue

index.vue:

<template>
  <main>
    <h1>Index Page</h1>

    <table border="1 px solid">
      <thead>
      <tr>
        <th>Name</th>
        <th>Symbol</th>
        <th>Price</th>
        <th>Details</th>
      </tr>
      <tr v-for="currency in data.data" :key="data.id">
        <td>{{ currency.name }}</td>
        <td>{{ currency.symbol }}</td>
        <td>{{ currency.price_usd }}</td>
        <td>
          <NuxtLink :to="'/currency/' + currency.id">{{ currency.id }}</NuxtLink>
        </td>
      </tr>
      </thead>
    </table>
  </main>
</template>

<script>
export default {
  async setup() {
    const {data} = await useFetch('/api/coinlore/tickers');

    return {
      data
    };
  }
}
</script>

and here is what I have for [id].vue

<template>
  <main>
    <h1>{{ data.data.name }} Detail page</h1>
    {{ $route.params.id }}
  </main>
</template>

<script>
export default {
  async setup() {
    const {data} = await useFetch('/api/coinlore/ticker?id=90');

    console.log(data);

    return {
      data
    };
  }
}
</script>

Going from this blog post I tried this

<template>
  <main>
    <h1>{{ data.name }} Detail page</h1>
    {{ $route.params.id }}
  </main>
</template>

<script>
export default {
  async setup() {
    const coin = reactive({});
    function fetchCoin(id) {
       const {data} = await useFetch('/api/coinlore/ticker?id=' + $route.params.id);
       coin = data;
    }

    watch('$route.params.id', fetchCoin)

    return {
      coin
    };
  }
}
</script>

but no dice there, either.

How can I simply 1) make my API call and 2) populate the data by using the id param in my [id].vue component?

Upvotes: 3

Views: 6607

Answers (3)

Rashmi Yadav
Rashmi Yadav

Reputation: 79

You can basically pass the id in route params like:

<NuxtLink :to="{path: '/currency', params : {id: currency.id} }">{{ currency.id }}</NuxtLink>

This piece of code will redirect to /currency/id

Also, the folder structure should be like:

/pages  
  /currency  
    [id].vue

Upvotes: 1

devzom
devzom

Reputation: 716

maybe it will help :_)

In index.vue it's better to use programatic routing:

<NuxtLink :to="{path: '/currency', params : {id: currency.id} }">{{ currency.id }}</NuxtLink>
// it will build link: `/currency/[id]`

and as posted by Tony19 there's a need to define route (useRoute hook) in the component:

// import in script
import { useRoute } from 'vue-router';

// define route from 'vue'
const route = useRoute()
    
// read ID from route params
const currencyId = route.params.id
    
// actually it's better use literal string for using dynamic data => better reading
const { data: coin } = await useFetch(`/api/coinlore/ticker?id=${currencyId}`);

Upvotes: 0

tony19
tony19

Reputation: 138286

Use the useRoute() hook:

import { useRoute } from 'vue-router';

export default {
  setup() {          👇
    const route = useRoute();                                       
    const { data: coin } = await useFetch('/api/coinlore/ticker?id=' + route.params.id);

    return { coin }
  }
}

demo

Upvotes: 3

Related Questions