Creating a load more feature with Vue

Having some trouble implementing a load more button that adds 10 more items to the page when clicked. The button code seems to be causing issues as all items still appear on the page and there are no errors in the console either. As a result, the button is not functioning properly.

Furthermore, I am attempting to incorporate this functionality with a filter function. Any examples or assistance would be greatly appreciated.

data() {
        return {
            estates:[],
            moreEstates: [],
            moreEstFetched: false,
        }
},

mounted() {
        axios.get('/ajax').then((response) => {
            this.estates = response.data
            this.insertMarkers();

        });
},

methods: {
        handleButton: function () {
            if(!this.moreEstFetched){
                axios.get('/ajax').then((response) => {
                    this.moreEstates = response.data;
                    this.estates = this.moreEstates.splice(0, 10);
                    this.moreEstFetched = true;
                });
            }
            var nextEsts = this.moreEstFetched.splice(0, 10);
            
            this.estates.push(nextEsts);
        },
},

computed: {
        one: function () {
            let filteredStates = this.estates.filter((estate) => {
                return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
                (this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
                (this.regions.length === 0 || this.regions.includes(estate.region))});

                if(this.sortType == 'price') {
                    filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
                }
                if(this.sortType == 'created_at') {
                    filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
                }

                filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
                filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
                filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});

                return filteredStates;
        },
},
<table class="table table-hover">
    <thead>
        <tr style="background-color: #fff ">
            <th scope="col">イメージ</th>
            <th style="width:175px;"scope="col">物件名</th>
            <th style="width:175px;"scope="col">住所</th>
            <th scope="col">販売価格</th>
            <th scope="col">間取り</th>
            <th scope="col">専有面積</th>
            <th scope="col">坪単価</th>
            <th style="width:90px;" scope="col">物件詳細</th>
        </tr>
    </thead>

  <tbody>
        <tr  v-for="estate in one">
            <td><img id="image" :src="estate.image" alt=""></td>
            <td>{{estate.building_name}}</td>
            <td>{{estate.address}}</td>
            <td>{{priceSep(estate.price)}} 万円</td>
            <td>{{estate.rooms}}</td>
            <td>{{xtendSep(estate.extend)}} m²</td>
            <td>{{estate.m2_price}}</td>
            <td><a :href="/pages/+estate.id">物件詳細</a></td>
        </tr>
  </tbody>

</table>

<button class="btn btn-primary loadmorebutton" @click="handleButton">Load more</button>

Answer №1

In response to @pyriand3r's observation about the asynchronous nature of the axios request, you can utilize async/await in the following way without making significant modifications to the existing code.

methods: {
  handleButton: function () {
      if(!this.moreEstFetched){
           axios.get('/ajax').then(async (response) => {
              this.moreEstates = await response.data;
              this.estates = this.moreEstates.splice(0, 10);
              this.moreEstFetched = true;
          });
      }
// It is important to note that you cannot splice a boolean value, only arrays.
      var nextEsts = this.moreEstFetched.splice(0, 10);

      this.estates.push(nextEsts);
  },
},

Explore more about Async/Await in JavaScript

Answer №2

Implemented some modifications to your code, please review the comments for clarity.

However, these changes mirror those made in the previous post.

data() {
        return {
            visible:true ,
            estates:[],
            moreEstates: [],
            moreEstFetched: false,
            size: 10,
            selectedPage:0,
            init: false,
            
        }
},
updated: function () { // triggered only once upon loading
            if (!this.init) {
                this.handleButton();
                this.init = true;
            }
        },
mounted() {
// The axios call here should be removed to use handleButton solely for data retrieval
       // axios.get('/ajax').then((response) => {
        //    this.estates =this.filterData(response.data)
          //  this.insertMarkers();
          //  this.showMore();
     //   });
},

methods: {

        filterData: function (data) {
let filteredStates = data.filter((estate) => {
                return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
                (this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
                (this.regions.length === 0 || this.regions.includes(estate.region))});

                if(this.sortType == 'price') {
                    filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
                }
                if(this.sortType == 'created_at') {
                    filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
                }

                filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
                filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
                filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});

return filteredStates;
        },
        showMore: function(){
                    if (Math.ceil( this.moreEstates.length / this.size) <= this.selectedPage +1 ){
            this.selectedPage++;
            
       // Use slice instead of splice as it's non-destructive
            var nextEsts = this.moreEstFetched.slice((this.selectedPage * this.size), this.size);
            
            this.estates.push(nextEsts);
           }else this.visible= true; // hide "Show More"
        
        },

        handleButton: function () {
            if(!this.moreEstFetched){
                axios.get('/ajax').then((response) => {
                    // Filter the entire dataset at once
                    this.moreEstates = this.filterData(response.data);
                    this.moreEstFetched = true;
                    // Relocated this line from elsewhere
                    this.insertMarkers(); 
                    this.showMore();
                });
            }else this.showMore();
        },
},
<table class="table table-hover">
    <thead>
        <tr style="background-color: #fff ">
            <th scope="col">イメージ</th>
            <th style="width:175px;"scope="col">物件名</th>
            <th style="width:175px;"scope="col">住所</th>
            <th scope="col">販売価格</th>
            <th scope="col">間取り</th>
            <th scope="col">専有面積</th>
            <th scope="col">坪単価</th>
            <th style="width:90px;" scope="col">物件詳細</th>
        </tr>
    </thead>
  <tbody>
        <tr v-for="estate in estates">
            <td><img id="image" :src="estate.image" alt=""></td>
            <td>{{estate.building_name}}</td>
            <td>{{estate.address}}</td>
            <td>{{priceSep(estate.price)}} 万円</td>
            <td>{{estate.rooms}}</td>
            <td>{{xtendSep(estate.extend)}} m²</td>
            <td>{{estate.m2_price}}</td>
            <td><a :href="/pages/+estate.id">物件詳細</a></td>
        </tr>
  </tbody>
</table>

<button v-if="visible" class="btn btn-primary loadmorebutton" @click="handleButton">Load more</button>

Answer №3

Frankly, I'm not entirely convinced that this is the optimal approach, but I opted for a much simpler method to accomplish it...

data() {
    return {
        moreEstates: 10,
    }
},
<table class="table table-hover>
  <tbody>
        <tr v-if="moreIndex < one.length"  v-for="moreIndex in moreEstates">
            <td><img id="image" :src="one[moreIndex].image" alt=""></td>
            <td>{{one[moreIndex].building_name}}</td>
            <td>{{one[moreIndex].address}}</td>
            <td>{{priceSep(one[moreIndex].price)}} million yen</td>
            <td>{{one[moreIndex].rooms}}</td>
            <td>{{xtendSep(one[moreIndex].extend)}} m²</td>
            <td>{{one[moreIndex].m2_price}}</td>
            <td><a :href="/pages/+one[moreIndex].id">Property Details</a></td>
        </tr>
  </tbody>
</table>

<button class="btn btn-primary loadmorebutton" @click="moreEstates += 10">View Next 10 Properties</button>

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

Using dangerouslySetInnerHTML in React within a Fragment

In my current project, I have a specific requirement where I need to format text in React and also include HTML rendering. Here's an example of what I'm trying to accomplish: import React, {Fragment} from "react"; import {renderToString} from " ...

Having trouble getting past the "Starting metro bundler" step when using the 'expo start' or 'npm start' command?

Currently, I am using React Native Expo to develop a mobile application. The process I followed includes the following steps: expo init myapp cd myapp expo start Initially, everything was running smoothly after executing these three commands. However, as ...

What measures does Redux take to ensure race conditions do not occur?

Recently, I delved into Redux and grasped the concept very well. However, there is one particular line in the official documentation that puzzled me: Because all changes are centralized and happen one by one in a strict order, there are no subtle race ...

Synchronizing data between two Vue components when deleting an item

Feeling uncertain about the approach I am taking with this data. Essentially, I have the following dataset: surrounding: { data: [ { id: 1, name: 'test' }, { id: 2, name: 'test' }, { id: 3, name: 'test& ...

Switch between visibility of objects with toggle button

I have set a background image on the body, and positioned a large box, footer, navigation bar, and header above it. In order to add functionality to slide these elements up and down, I've created two buttons with classes 'slideUp' and &apos ...

Save the data in Redux and access it back

I am currently using material-ui-dropzone to upload an array of files and store them in redux However, when I try to retrieve the file from the redux state, it is not recognized as type "File" and appears differently in devtools https://i.stack.imgur.com ...

The fade effect on an element cannot be achieved using setTimeout

I'm trying to call a tooltip and hide it after 9 seconds, but for some reason, it's not working as expected. The issue I'm facing is that the "tooltip" only hides after it initially loads. It doesn't respond when I click on the "Touch ...

I'm puzzled, can anyone provide clarification on the concept of xml?

Recently, Sheshank S. provided me with a solution to my question, but I failed to grasp its meaning. Can someone please explain it to me? Despite looking through various tutorials on websites and videos, none of them have been able to clarify what this cod ...

Modify path and refresh display upon ajax call to node server

Recently, I made the decision to utilize a Node server as a proxy for making API calls to third-party public APIs from my front end. After successfully sending a request to my Node endpoint and then to the third-party API, I received the expected response. ...

What is the best way to showcase the chosen items in a dropdown menu?

There seems to be an issue with the selected item not appearing in the input field. export default function BasicSelect() { const [sortBy, setSortBy] = useState(""); const [condition, setCondition] = useState(""); const [delivery, ...

Turn off error notifications from eslint parsing

Within my code, there is a conditional export that looks like this: if (process.env.NODE_ENV === 'testing') export myFunc; While in es6, this type of statement is typically not allowed due to the requirement for imports and exports to be top- ...

Guide on converting JSON object to condensed rows when using ng-repeat

From the database, I am receiving a JSON object which is one large object: $scope.totalsum = { "A1": 1155000, "A2": null, "A3": 2133, "A31": 29292, "A32": 2321, "A33": 232342, ...

Getting JSON data from an Angular JS controller can be achieved by utilizing the built-in

My user login function includes a method called logincheck, which takes in parameters and sends a request to the server. Upon success, it redirects the user to the dashboard with the member ID. this.logincheck = function(log) { var pa ...

Enable the input field once the checkbox has been marked

Here is a checkbox example: <div class="form-group"> <input type="checkbox" id="examination" class="form-control" name="exam" placeholder="Enter Title"> <label>Enable Exam</label> </div> Additionally, I have a disabled inpu ...

The integration of HTML and CSS using ng-bind-html appears to be malfunctioning

<ion-item ng-bind-html="renderHtml(word[key])"> </ion-item> When referring to word[key], it represents: <ul> <li>item 1</li> <li>item 2</li> <li>item 3</li> </ul> This is the CSS being u ...

Checking for correct format of date in DD/MM/YYYY using javascript

My JavaScript code is not validating the date properly in my XHTML form. It keeps flagging every date as invalid. Can someone help me figure out what I'm missing? Any assistance would be greatly appreciated. Thank you! function validateForm(form) { ...

Using jQuery JSONP only functions with URLs from the same site

I am looking to send a request to an API that returns data in json format. The API is located on a sub-domain of the domain where my script will be running (although currently it's on a completely different domain for development, localhost). My unde ...

Encountering a "DOM Exception 11: InvalidStateError" when attempting to use websocket.send

I encountered the following error message: DOM Invalidate exception 11 This error is coming from the code snippet below, but I'm having trouble identifying the root cause. /*The coding style may appear pseudo-stylish with potential syntax errors*/ ...

Working with Ext JS: Dynamically adjusting panel size when the browser window is resized

I am facing an issue with a side panel in Ext.js. Everything is working fine until I resize the browser, at which point some components of the panel get cut off. Is there a way to make the panel resize automatically when the browser is resized? { ...

Is there a way to modify the text of image URLs using JavaScript?

My method of replacing a specific word in text works like this: document.body.innerHTML = document.body.innerHTML.replace(/katt/g, "smurf"); However, when I try to replace an image URL in HTML using the same line of code, it doesn't seem to work. H ...