How can I make v-for display additional profiles to achieve an infinite scroll effect?

Hey there! I've got a Firestore database set up to fetch profiles and display them on a page using v-for. I want to implement infinite scroll for a smoother user experience. Here's the JavaScript composable code I'm working with:

import { projectFirestore } from "../Firebase/Config";
import { ref } from "vue"

const getPremium = () => {
    const Premium = ref([])
    const error = ref(null)

    
const load = async () => {
    try{
        const res = await projectFirestore.collection('Premium').limit(4).get()
        

        Premium.value = res.docs.map(doc => {
           console.log(doc.data())
           return {...doc.data(), id: doc.id}
        })
    }
    catch (err){
        error.value = err.message
        console.log(error.value)
    }
    const newPicturesCount = await load()
    if (newPicturesCount > 0) {
        return load() // More profiles to come
      }

      return console.log("done") // Done with the profiles
    }

    return { Premium, error, load }
}

export default getPremium

I was expecting the profiles to load consecutively with a v-for statement, enhancing user experience and reducing loading times. However, while the profiles are being logged as they load, they're not appearing in the v-for loop as expected. It seems like the same 4 profiles are being retrieved repeatedly, which is not my intention. Here's the Vue end for a complete overview:

<div v-for =" Premiums in Premium" :key="Premiums.id" >
 <router-link :to="{ name: 'Samplepremium', params: { id: Premiums.id }}">
 <div class= "hover:scale-105 transition ease-in-out duration-300 bg-neutral-800 hover:bg-neutral-900 active:bg-neutral-900 text-neutral-400 font-bold rounded-xl">
  <br>
     <p class="text-xl">{{ Premiums.Name }}</p>
     <div class="relative">
     <img :src= "Premiums.Pic1"  class="object-contain px-1 inline-block w-96 h-44 md:w-60 md:h-80 lg:w-60 lg:h-80 xl:w-60 xl:h-80 2xl:w-60 2xl:h-80 transition ease-in-out duration-300">
     <p class="bg-red-700 text-slate-300 text-xl absolute top-0 w-full">{{ Premiums.detail1 }}</p>
     <p class="bg-red-700 text-slate-300 text-xl absolute bottom-0 w-full"> {{ Premiums.detail2 }} </p>
    </div>
     <div class="grid grid-cols-2 grid-rows-fit text-left ml-6">
     <p>Age:</p>
     <p>{{ Premiums.detail3 }}</p>
     <p>Location:</p>
     <p>{{ Premiums.detail4 }}</p>
     <p>Rates:</p>
     <p>{{ Premiums.detail5 }} /hr</p>
     <p>Phone:</p>
     <p>{{ Premiums.detail6 }}</p>
   
    </div><br>
  </div>
  </router-link>
  </div>
</template>

If you have any suggestions on how to keep track of the current document and properly v-for the profiles after the initial load, I would greatly appreciate it. Thank you!

Answer №1

It seems like the issue lies in your current implementation. The load() function is fetching four profiles from Firebase and updating the value of Premium with the new data each time it is called. This means that you are retrieving the same values repeatedly, causing the previous data to be replaced by the new one and resulting in data loss.

To address this issue, you should use a cursor to add data to the existing Premium value.

You can make changes to the getPremium() function as follows:

const getPremium = () => {
    const Premium = ref([])
    const error = ref(null)
    let lastDoc = null; 

    const load = async () => {
        try {
            let query = projectFirestore.collection('Premium').orderBy('id').limit(4)
            if (lastDoc) {
                query = query.startAfter(lastDoc)
            }

            const res = await query.get()

            if (!res.empty) {
                lastDoc = res.docs[res.docs.length - 1]

                // Append new results to existing ones

                Premium.value = [...Premium.value, ...res.docs.map(doc => {
                    console.log(doc.data())
                    return {...doc.data(), id: doc.id}
                })]
            }
        }
        catch (err){
            error.value = err.message
            console.log(error.value)
        }
    }

    return { Premium, error, load }
}

export default getPremium

Don't forget to include the following imports at the beginning of your file:

import { projectFirestore } from "../Firebase/Config";
and import { ref } from "vue".

Now you can simply implement the @scroll event in your HTML section:

<div @scroll="checkScroll" style="overflow-y: auto; height: 100vh;">
    <div v-for="Premiums in Premium" :key="Premiums.id" >
        <!-- Add your HTML content here -->
    </div>
    <button v-if="isLoading" type="button">Loading...</button>
</div>

And define the checkScroll() method as follows:

checkScroll() {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
            this.load(); 
    }
}

Hopefully, this provides a clear solution to your problem 🌷

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Mastering the art of utilizing Async in combination with waterfall and Recursion in node

I've developed a script for transferring data from Dynamo to a MySQL database. Initially, I encountered performance issues on the SQL side due to not using asynchronous calls. To address this, I integrated the async library to throttle the Dynamo segm ...

Display a particular element when hovered over

Is there a way to make only individual elements pop up on hover instead of all of them at once? items: [{ item: "Book", info: "Lorem ipsum", displayInfo: false }, { item: "Pen", info: "Lorem ipsum", displayInfo: false }, ...

"Encountered a 400 Error while trying to access the OpenAI

var openairequest = new XMLHttpRequest(); const payload = ({ "model": "text-davinci-003", "prompt": "say this is a test" }); console.log(payload) openairequest.open("POST",`https://api.openai.com/v ...

Establishing a dynamic database feature (such as a real-time leader board) on a website

Recently, I designed a fun JavaScript game for my website and now I am contemplating adding a leaderboard feature. However, I am unsure about which type of database would be the best fit - MongoDB, SQLite, or something else entirely. I have heard that SQ ...

What is the best way to exhibit information from a lone table column in a modal using Angular 7?

Is there a way to have an "edit" button beside each row in the appointments table that triggers a modal popup allowing users to change appointment dates? Unfortunately, I'm facing an issue where the modal does not pop up and my screen turns white. ** ...

Enhance the efficiency of your JavaScript code by minimizing repeated selectors

I've been working on a JavaScript project where I came across the following lines of code: $('#content').on('click', 'input[type=submit]', function(){ $('#content').on('click', 'a.removebutton&a ...

Tips on dividing and recycling mongodb connection in Node.js

I am currently troubleshooting the connection to MongoDB using Node.js. The code I have in a file named mongodb.js is as follows: const mongoClient = require('mongodb').MongoClient; const env = process.env.NODE_ENV || 'development'; co ...

Save to a JSON file

Hey there, I'm having some trouble with pushing a temporary value to a JSON file using the command "MyJSON.name.push". It keeps giving me an error saying "Undefined is not an object". I've tried different approaches and using JavaScript arrays wo ...

Is the for loop programmed to stop at the first match?

I've been working on filtering a txt file using nodejs. Here's my code snippet: const fs = require('fs') let list = fs.readFileSync('./newmR.txt', 'utf-8').split('\r\n') console.log(list.length) ...

Non-functioning Tooltips on Google Charts

Currently, I am working on integrating Google Chart with ASP.NET and linking it to a SQL Server database. I have encountered an issue while attempting to customize the tool tip. Below is the Header Code: <script src="js/jquery/jquery-1.10.2.js" type=" ...

Learn how to extract data from the "this" object in JavaScript

Can anyone help me with retrieving the numbers generated by this code snippet? $("#100wattaren") .countdown("2018/01/01", function(event) { $(this).text( event.strftime('%D days %H hours %M minutes %S seconds') ); }); When I con ...

Is there a feature in VS Code that can automatically update import paths for JavaScript and TypeScript files when they are renamed or

Are there any extensions available for vscode that can automatically update file paths? For example, if I have the following import statement: import './someDir/somelib' and I rename or move the file somelib, will it update the file path in all ...

A guide to finding the mean in Angular by utilizing JSON information

import { Component, OnInit } from "@angular/core"; import { MarkService } from "../app/services/marks.service"; @Component({ selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.scss"] }) export class AppComp ...

Encountering a Laravel error related to "SymfonyComponentHttpKernelExceptionHttpException"

After transferring my Laravel and Vue JS application to our server, I encountered an error that reads: Symfony\Component\HttpKernel\Exception\HttpException A similar issue was reported here, but unfortunately no solution was provid ...

Leveraging a component as a property of an object in Vue version 3

I'm trying to figure out if there's a way to use a Component as a property in Vue 3. Consider the TypeScript interface example below: import type { Component } from 'vue' interface Route { url: string icon: Component name: ...

Using Laravel to Incorporate Vue Component

Exploring Laravel (using version 6) and I'm trying to figure out how to ensure that my view is utilizing my Vue component. Specifically, I want to render the HelloWorld.vue component in the albums.blade.php view file. In my app.js, I have registered ...

Build a Node.js application with Express to host static files

I am attempting to provide my static files "web.html" and "mobile.html", but I want them to be served only if the user is accessing from a web or mobile device. After some research, I came up with this code: var express = require('express'); va ...

What is the best approach to comply with the EsLint rule "react-hooks/exhaustive-deps" and properly implement componentDidMount using hooks in React with a warning level?

After reviewing the React documentation, it appears that componentDidMount is now implemented using hooks as shown below: useEffect(() => { // your code here }, []) For example, if you wish to make an API call within this hook: useEffect(() => { ...

Is there a way in JavaScript to disable a function's functionality?

I am dealing with a function that includes an if statement and an onclick function. My goal is to prevent the entire function from running if the if statement evaluates to true. I have attempted using return false, but it did not yield the desired outcom ...

VueJs and Vuetify come together in perfect harmony in the V-select outlined component

I am new to using VueJS and Vuetify. I have noticed that with v-select outlined, the label is not directly on the border of the field. Instead, I have to click in the field first before it appears. Can anyone explain why this is happening? Here is my code ...