I'm trying to make a button that updates api url.
<template>
<div>
<div v-for="post in posts">
<li>{{ post.title }}</li>
</div>
<button @click="nextPage">New posts</button>
</div>
</template>
<script>
export default {
data() {
return {
posts: [],
totalPosts: null,
postsPerPage: 20,
pageNumber: 1,
totalPages: null,
}
},
async fetch() {
const param = {
params: {
_page: this.pageNumber,
_limit: this.postsPerPage,
},
}
const response = await this.$axios.get(
'https://jsonplaceholder.typicode.com/posts',
param
)
this.totalPosts = response.headers['x-total-count']
this.posts = response.data.reverse()
this.totalPages = this.totalPosts / this.posts
},
methods: {
fetchPost() {
this.$fetch()
},
nextPage() {
this.pageNumber = 1
},
previousPage() {
this.pageNumber -= 1
},
},
fetchOnServer: false,
}
</script>
In jsonplaceholder, I can set a page number and post limit, like https://jsonplaceholder.typicode.com/posts?_page=1&_limit=20. So I tried to make a button that updates page parameter in that url.
But when I made nextPage method and add this to button, I can see that pageNumber data is going up but not re-calling api using that pageNumber.
Is there way I can re-call api or re-render in nuxt?
CodePudding user response:
Your methods nextPost() and previousPost() only update your pageNumber. You need to call your method fetchPost() with the updated parameters. Have a look at this video by Debbie O'Brian on youtube - youtube.com/watch?v=qD1Q3nllYRY&t=148s
CodePudding user response:
You're code is almost correct, but just minor corrections.
- Move all your calls to external APIs within the
methods
object invue
. Do not define the outside the methods object. - Whenever you make a call to a external API mark the method as
async
, as await can only be used within anasync
function. - Move all your variables that will be used within the DOM to the
data
method. You had defined thefetchOnServer
outside of the data function.
Now coming to why your code wasn't working, it's because you haven't called the fetch
post method on click of the button. You've only incremented the page number. That will not help. Once the page number has been incremented, you need to re-call the fetch
posts method in order for nuxtjs
to render the need content reactively.
Optimized Solution
Vue.config.productionTip = false
Vue.config.devtools = false
new Vue({
el: "#app",
data() {
return {
posts: [],
totalPosts: null,
postsPerPage: 20,
pageNumber: 1,
totalPages: null,
fetchOnServer: false,
}
},
methods: {
async fetchPost() {
const param = {
params: {
_page: this.pageNumber,
_limit: this.postsPerPage,
},
}
const response = await axios.get('https://jsonplaceholder.typicode.com/posts', param);
this.totalPosts = response.headers['x-total-count'];
this.posts = response.data.reverse()
this.totalPages = this.totalPosts / this.posts
},
nextPage() {
this.pageNumber = 1;
// call the fetchPost function when the button is clicked
this.fetchPost();
},
previousPage() {
this.pageNumber -= 1;
// call the fetchPost function when the button is clicked
this.fetchPost();
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<div id="app">
<template>
<div>
<div v-for="post in posts">
<li>{{ post.title }}</li>
</div>
<button @click="nextPage">New posts</button>
<button @click="previousPage">Previous posts</button>
</div>
</template>
</div>