anhnd's avatar
Level 2

Problems with pagination when building a SPA with vuejs using vue-router

Hi all, I got a problem when building SPA with vuejs using vue-router.

Everything works great without pagination. But when i go to next page. It is not update new Route

Somebody helps me out, please!

Here is my code:

<template>
    <div class="category-view">
        <topic
                v-for="topic in topics"
                :topic="topic">
        </topic>

        <div class="Pagination">

            <router-link
                            v-if="page > 1"
                            :to="{ name: 'category', params: { categoryId: categoryId}, query:{page : page + 1}}"
                            class="Page-link Page-link--prev" replace>
                    Back
            </router-link>

            <router-link
                            v-if="page < lastPage"
                            :to="{ name: 'category', params: { categoryId: categoryId}, query:{page : page + 1}}"
                            class="Page-link Page-link--next" replace>
                Next
            </router-link>

        </div>

    </div>
</template>

<script>
import Topic from './Topic.vue';

export default {

  components: { Topic },

  data () {
    return {
      topics: [],
      categoryId: 0,
      page: 1,
      lastPage: 1
    }
  },

 created(){

       this.fetchTopics();
 },

 methods:{

    fetchTopics(){

        this.categoryId = this.$route.params.categoryId;
        this.page = this.$route.query.page || 1;


        axios.get('/api/categories/'+ this.categoryId +'/topics')
             .then(response => {

                this.topics = response.data.data;
                this.lastPage = response.data.last_page;
             })
             .catch(error => {
                 console.log("Error..." + error.response)
              });

    }
 }
}

</script>
0 likes
8 replies
jurjen's avatar

You could put a watcher on this.$route.params.page and then fetch new topics when the value changes:

created() {
    this.fetchTopics()
},
methods: {
    fetchTopics() {
        // current code to fetch your topics
    }
},
watch: {
    '$route.params.id': 'fetchTopics'
}

Your API call however doesn't seem to take in account the current page.

jurjen's avatar

Can't really tell what goes wrong if you don't share any code. Does the fetchTopics method get triggered when you change the route id param?

anhnd's avatar
Level 2

@jurjen I didn't change the id paramater. I only change the page query to paginate data per page.

anhnd's avatar
Level 2

I found a way to make it work but i don't know whether it is optimize

<template>
    <div class="category-view">
        <topic
                v-for="topic in topics"
                :topic="topic">
        </topic>

        <div class="Pagination">
            
            <a class="Page-link Page-link--prev"
                v-if="page > 1"
                @click="fetchTopics(page - 1)"
            >Back</a>

            <a class="Page-link Page-link--next"
                v-if="page < lastPage"
               @click="fetchTopics(page + 1)"
            >Next</a>
            
        </div>

    </div>
</template>

<script>
import Topic from './Topic.vue';
export default {
  components: { Topic },

  data () {
    return {
      topics: [],
      categoryId: 0,
      page: 1,
      lastPage: 1
    }
  },

 created(){

       this.fetchTopics();
 },

 methods:{

    fetchTopics(currentPage = 1){
        this.categoryId = this.$route.params.categoryId;

        axios.get('/api/categories/'+ this.categoryId +'/topics?page=' + currentPage)
             .then(response => {
                this.page = currentPage || 1;
                this.topics = response.data.data;
                this.lastPage = response.data.last_page;
             })
             .catch(error => {
                 console.log("Error..." + error.response)
              });
    }
 }
}

</script>
anhnd's avatar
anhnd
OP
Best Answer
Level 2

And this is the second solution: For someone that want to trigger the : 'fetchTopics' method when the route query change.

<template>
    <div class="category-view">
        <topic
                v-for="topic in topics"
                :topic="topic">
        </topic>

        <div class="Pagination">
            <router-link class="Page-link Page-link--prev"
                         v-if="page > 1"
                         :to="{name: 'category', params: {categoryId: categoryId}, query:{page: page - 1}}"
            >Back</router-link>

            <router-link class="Page-link Page-link--next"
                         v-if="page < lastPage"
                         :to="{name: 'category', params: {categoryId: categoryId}, query:{page: page + 1}}"
            >Next</router-link>

        </div>

    </div>
</template>

<script>
import Topic from './Topic.vue';
export default {
  components: { Topic },

  data () {
    return {
      topics: [],
      categoryId: 0,
      page: 1,
      lastPage: 1
    }
  },

 created(){
       this.fetchTopics();
 },

 methods:{

    fetchTopics(){

        this.categoryId = this.$route.params.categoryId;
        let _page = this.$route.query.page || 1;

        axios.get('/api/categories/'+ this.categoryId +'/topics', {params:{ page: _page}})
             .then(response => {
                this.page = _page;
                this.topics = response.data.data;
                this.lastPage = response.data.last_page;
             })
             .catch(error => {
                 console.log("Error..." + error.response.data)
              });
    }
 },

 watch: {
    '$route' (to, from) {
      // react to route changes...
      this.fetchTopics();
    }
  }
}
</script>

Please or to participate in this conversation.