chrisgrim's avatar

Working with Pagination and infinite loading

Hi, I am trying to setup infinite loading in my Vue component. I realized that I needed to combine pagination with the infinite loading so it knows where to stop and start with pulling in more events as the user scrolls. I added pagination and immediately hit an issue. Pagination no longer just sends the events like get() does. When I do a return of $events with pagination I get

{
"current_page": 1,
"data": [],
"first_page_url": "http://showbelow.test?page=1",
"from": 1,
"last_page": 2,
"last_page_url": "http://showbelow.test?page=2",
"next_page_url": "http://showbelow.test?page=2",
"path": "http://showbelow.test",
"per_page": 4,
"prev_page_url": null,
"to": 4,
"total": 8
}

I am pulling event in like this <event-listing :events="{{$events}}"></event-listing> but that no longer works. I am sort of stuck. Do I need to send the data as JSON? Here is my vue component file for event-listing

<template>
    <div>
        <a v-if="isGuest" class="btn" href="/login">Please login</a>
        <div v-if="isLoggedIn">
            <button @click="setUserEmail(`updated-${loggedInUser.email}`)"> Update Email </button>
            <div>user email : {{ loggedInUser.email }}</div>
        </div>  
        <h2>Our Latest Events</h2>
        <div id="app">
            <div id="grid-section">
                <div v-for="event in filteredEvents">
                    <event-listing-item :user="user" :event="event"></event-listing-item>
                </div>
            </div>
            <div id="grid-section">
                <div v-for="event in list">
                    <event-listing-item :user="user" :event="event"></event-listing-item>
                </div>
                <infinite-loading @infinite="infiniteHandler"></infinite-loading>
            </div>
        </div>
    </div>
</template>

<script>
    import _ from 'lodash';
    import usersMixin from '../../mixins/users.js';
    import InfiniteLoading from 'vue-infinite-loading';

    const api = '//hn.algolia.com/api/v1/search_by_date?tags=story';

    export default {
        props: {
            events: { type:Array },
            user: { type:Object },
        },

        mixins: [
            usersMixin,
        ],

        components: {
            InfiniteLoading,
        },

        data() {
            return {
                allEvents: this.events,
                value: '',
                searchOptions: this.events,
                list: [],
            }
        },

        computed: {
            filteredEvents(){
                if( !this.value ) {return this.allEvents;}
                    const search = this.value.eventTitle.toLowerCase().trim();
                    return this.events.filter(c => c.eventTitle.toLowerCase().indexOf(search) > -1);
            }
        },

        methods: {

            initializeEventObject() {
                return {
                    id: '',
                    eventTitle: '',
                }
            },

            infiniteHandler($state) {
                    const data = this.events;
                    if (data) {
                      this.list = this.list.concat(data);
                      $state.loaded();
                    } else {
                      $state.complete();
                    };
            },


        }
    };
</script>

Thanks

0 likes
3 replies
MaverickChan's avatar
Level 47

in my controller , i return a collection as json object

you can change the name to event

    
    export default {
        mounted () {
            this.getPosts ()
        }

        props : {
            url: String,
        },

        data () {
            return {
                collection : {
                    data : []
                },
                query: {                   

                    limit: 10,
                    page: 1

                },

            }

        },

        
        methods : {

            getPosts () {
                const params = {
                    ...this.query
                }

                axios.get(this.url , {params : params})
                    .then(
                            response => {
                                this.collection = response.data.collection
                                this.query.page = response.data.collection.current_page
                            }
                        )

                    .catch((error) => {

                    })
                    .finally(() => {                    

                    });

            },

            changePerpage () {
                this.query.page = 1
                this.getPosts ()
            },

            nextPage () {
                if (this.collection.next_page_url) {
                    this.query.page = Number(this.query.page) + 1
                    this.getPosts ()
                }
            },

            prevPage () {
                if (this.collection.prev_page_url) {
                    this.query.page = Number(this.query.page) - 1
                    this.getPosts ()
                }

            },

        }
    }

chrisgrim's avatar

Hi @maverickchan

So you don't pass any variable props to the component? Instead you get the json by axios?

MaverickChan's avatar

@CHRISGRIM -

No , you don't have to pass a prop. Many of the logics is in the Model, controller just do some dispatch work.

for example:

in controller , just one action

public function dataviewer () {

        return response () 

            ->json([

                'collection' => Post::AdvancedFilter()

            ]);

    }

in my Model

public function scopeAdvancedFilter ($query) {
    
    // $query is for data query such as searching , selection , you need to write your own
    //you can do more in this part , such as chained orderby , paginate, just return a collection , and done

    }

Please or to participate in this conversation.