0

I have some pagination on an Api route which was used to fetch the post's data.

When the pagination is on page 2, I would like to add the fetched data from the page and add to the existing array.

Function used to fetch the data

const posts = ref([]);
const page = ref(1);

const getPosts = async (page) => {
        await axios
            .get("/api/explore/gallery/?page=" + page)
            .then((response) => {
                if (page === 1) {
                    posts.value = response.data;
                } else {
                    posts.value = { ...posts.value, ...response.data };
                }
            });
    };

So when the page is 2 onward, the fetched data will add to the existing array.

The result if I used posts.value = { ...posts.value, ...response.data };

The id start from 51 instead of 1 - 100.

The id start from 51 instead of 1 - 100.

I have also tried posts.value = [ ...posts.value, ...response.data ]; but returned

PostApi.js:12 Uncaught (in promise) TypeError: Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.
    at _nonIterableSpread (PostApi.js:12:39)
    at _toConsumableArray (PostApi.js:10:131)
    at eval (PostApi.js?c0c4:15:21)

response.data look like this

enter image description here

post.value look like this

enter image description here

7
  • 1
    An array uses [ ... ] not { ... } Also, you need to make sure you're spreading the actual array, not something else. Why are you referring to posts.value is posts is an array? There's maybe a posts[0].value but an array does not have a .value Commented Apr 20, 2022 at 9:21
  • 1
    You can use the concat method to add value to the existing array : posts.value = posts.value.concat(response.data) Commented Apr 20, 2022 at 9:28
  • @ChrisG, i referred to this solution from other people stackoverflow.com/a/71110698/17737657 Commented Apr 20, 2022 at 10:08
  • 1
    In other words, the loaded array is response.data.data and the existing array is post.value.data, which means you need post.value.data = [ ...post.value.data, reponse.data.data ] Commented Apr 20, 2022 at 10:10
  • 1
    @Chai Fuu Wong It seems like ref can't take an array as it's a mutable ref object, which has a single property value that points to the inner value. Try instantiate the array with const post = {value: []} or const post = [] Commented Apr 20, 2022 at 11:42

2 Answers 2

1

You could do this with a cache to provide more control over how much data accumulates on the client. This answer provides a reasonable looking LRU cache. Combining it with your api might look like this...

const cache = new LRU(8);

const getPosts = async (page) => {
    const result = cache.get(page);
    if (result) return Promise.resolve.result;
    return await axios
        .get("/api/explore/gallery/?page=" + page)
        .then((response) => {
            cache.set(page, response.data);
            return response.data;
        });
};

Your markup would show the current value of posts. Whatever user event that triggers your paging would do this...

// in an async method
this.posts = await getPosts(pageComputedFromUI);

This would have about the same effect as your solution (which caches everything and never expels anything), but with the benefit of memory kept under your control -- and at the cost of more network requests.

Sign up to request clarification or add additional context in comments.

2 Comments

maybe we should continue to discuss in pm, cuz I'm not sure if I implemented it correctly
discord.gg/Fx5GXYyq, here's a server for programmers to discuss or add me at discord suprême_GuNz#9742
0

I have found the solution,

const getPosts = async (page) => {
    await axios
        .get("/api/explore/gallery/?page=" + page)
        .then((response) => {
            if (page === 1) {
                posts.value = response.data;
            } else {
                posts.value = {
                    ...posts.value,
                    data: [...posts.value.data, ...response.data.data],
                };
            }
        });
};

3 Comments

Glad it works, but consider this: often, the reason an api pages is because there's too much data for the client to handle all at once. A client that navigates to too many pages might end up with too much data. The simpler alternative is to just fetch on every page change, and cache at most one or two pages in each direction.
@danh, Thx for your suggestion, but maybe you can explain in more detail cuz I am not quick to understand.
@danh, what would be the best approach to handle things like infinite scroll to display the posts? currently, i am using pagination(laravel) in the backend and fetching them in the front end, and storing them in an array, as you can see above ? but like you said the client would end up getting much and much more data .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.