The console log message persists even though the condition statement is present - Vue2

The main goal of my code is to trigger the fetchNumbers() function (which retrieves numbers from an API) when a user scrolls to the bottom of the page, creating an infinite scroll effect. However, I'm encountering an issue with the condition inside the axios promise (then) block because it's causing two console.log outputs to occur simultaneously. It seems like the condition is being ignored altogether.

The method I am using is as follows:

methods: {
fetchNumbers (type = 'default', offset = 0, limit = 0) {
  return axios.get(globalConfig.NUMBERS_URL)
    .then((resp) => {
       if (type === 'infinite') {
         console.log('infinite fired')
       } else {
         console.log('default fired')
       }
    })
}

The issue is suspected to be in the mounted function:

mounted () {
  window.onscroll = () => {
    let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight > document.documentElement.offsetHeight - 1
    if (bottomOfWindow) {
      this.fetchNumbers('infinite')
    }
  }
}

Upon reloading or entering the page, I'm seeing both console outputs appearing simultaneously:

default fired infinite fired

Sometimes the order of the outputs is reversed.

UPDATE.

Methods that call the fetchNumbers() function:

async created () {
  await this.fetchNumbers()
}

showCats (bool) {
  this.showCategories = bool

  if (!bool) {
    this.category = [1]
  } else {
    this.category = []
  }
  this.isActive = true
  this.fetchNumbers()
}

UPDATE 2.

I have identified the issue and will provide more details in an answer.

UPDATE 3.

The problem indeed lies within the onscroll function. I have three pages in my application: the main page, numbers page, and contact page. If I navigate from the numbers page (where the onscroll function is mounted) to the main or contact page, the onscroll function remains attached and triggers the API call when I scroll to the bottom, even if it's not the numbers page. Is there a way to limit this function to only the numbers page?

Answer №1

I needed to deactivate the onscroll listener when the component is destroyed:

destroyed () {
  window.onscroll = null
}

By doing this, the listener won't be attached when I visit the main or contact page.

Additionally, I had to transfer the onscroll listener from mounted to created to prevent it from firing twice:

created () {
  window.onscroll = () => {
    let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight > document.documentElement.offsetHeight - 1
    if (bottomOfWindow) {
      this.isActive = true
      this.fetchNumbers('infinite', counter++ * this.limit)
    }
  }
}

Answer №2

It seems like fetchNumbers is being called twice. Consider logging every context as type.

fetchNumbers (type = 'default', offset = 0, limit = 0) {
   return axios.get(globalConfig.NUMBERS_URL)
     .then((resp) => {
       if (type === 'infinite') {
         console.log(type,'infinite fired');    //this will always print 'infinite', 'inifinite fired'
       } else {
         console.log(type,'default fired');     //this will print the caller's name and 'default fired'
         type = 'default';                      //after logging reset type to 'default' for further execution
       }
     })
}

async created () {
  await this.fetchNumbers('created');
}

showCats (bool) {
  this.showCategories = bool
   
   if (!bool) {
     this.category = [1];
   } else {
     this.category = [];
   }
   this.isActive = true
   this.fetchNumbers('showCats');
}

It appears that either created or showCats is being triggered simultaneously with window.onscroll. The inconsistent order suggests a race condition between these two methods.

UPDATE

If your desired page is nested within a div with id="number_page_div_id" (adjust its height and position if necessary), this solution should work:

created () {
  let element = getElementById('numbers_page_div_id');
  element.onscroll = () => {        
    let bottomOfWindow = element.scrollTop + window.innerHeight > element.offsetHeight - 1;
    if (bottomOfWindow) {
      this.fetchNumbers('infinite')
    }
  }
}

Answer №3

Consider using a different approach for handling conditions instead of if/else, such as the following:

.then((resp) => {
       switch (type) {
         case 'infinite':
           console.log('infinite fired');
           break;
         case 'default':
           console.log('default fired');
           break;
       }
    })

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

Ways to navigate private property using the App Component in Angular 4

I have successfully implemented code in my app component to retrieve the current URL and display it in app.component.html. app.component.ts import { Component } from '@angular/core'; import { Router } from '@angular/router'; @Compone ...

Tips for showcasing information from the tmdb api by leveraging the value or data obtained from a separate api

I am currently working on a project that involves displaying movie data using the tmdb api. I receive the response from my own api which only includes the id of the tmdb movie. Here is an example of the response: [ { "id": 0, "tit ...

Keeping data external to promises in protractor

In my angular app, I have a timeline feature that displays the names and descriptions of players. All player names are under the common class player-title.ng-binding, while all player descriptions share the class .player-description.ng-binding To retrieve ...

Event in Bootstrap modal fails to activate

I've been attempting to link some code to execute when my modal is opened. Despite successfully opening the modal, I am puzzled as to why my event fails to trigger. Below is the structure of my modal: <div id="details" class="modal fade" style="d ...

AngularJS: Tips for bypassing filtering when inputting values outside of the range [1,2,3,4]

Is there a way to prevent filtering when entering certain numbers in the text box, like 0 or 5? <div ng-app=""> <input type="text" ng-model="search"> <div ng-repeat='val in [1,2, 3, 4] | filter:search'> {{val}} </div> ...

Changes to the folder structure in Laravel are not reflected in Vue components

Recently, while working with Laravel and Vue.js, I came across an issue after rearranging my files to upload the project online. Now, whenever I update the Vue files, the changes don't seem to reflect. Seeking assistance from the experts in this commu ...

Issues with error handling in ExpressJS arise frequently

In the server.js file, towards the very end, there is a block of code that appears to handle errors: app.use(logErrors); function logErrors (err: Error, req: Request, res: Response, next: NextFunction) { console.log(err); mongoDal ...

How to extract selected value from a dropdown menu in a React component

Is there a way for me to retrieve the chosen value from the dropdown menu? The select dropdown contains 12 options. My goal is to capture the selected value and then utilize it in handlecolumnchange to manipulate the number of columns added or removed. Des ...

The latest version of Ant Design, version 4, causes issues with React Testing Library tests for the Select

I recently updated my React project to ant design v4 and encountered issues with tests that involve a Select, AutoComplete or Tooltip. When interacting with these components, the modal or select options are not rendering in JSDOM as expected. This function ...

Change the icon switch from fas fa-lock-open to fas fa-lock by adding an event listener for a click action

let lockIcon = document.createElement("i"); lockIcon.setAttribute("class", "fas fa-lock-open"); lockIcon.setAttribute("id", color + "lock"); Is there a way to toggle between the icons fas fa-lock-open and fas fa-lock when clicking using a ...

Vuejs unstyled content flash

I encountered an issue while loading a page with Vue. Initially, I am able to access variables like @{{ value }} but once the page is fully loaded, the variable becomes invisible. How can I resolve this issue? I have already included Bootstrap and all scri ...

What is the process for converting a URL or HTML document to a PDF using the html2pdf JavaScript library?

I am working on creating a button that utilizes the html2pdf library to convert an HTML page into a PDF. Instead of selecting an element with query selector or getElementById, I would like to pass a URL because the page I want to convert is not the same as ...

Triggering createEffect in SolidJS with an external dependency: A guide

Is there a way to use an external dependency to trigger the createEffect function in Solid, similar to React's useEffect dependency array? I am trying to execute setShowMenu when there is a change in location.pathname. const location = useLocation() ...

What is the syntax for accessing a dictionary item within a <span> tag using JavaScript?

I'm working on a new functionality for a website that involves using a dictionary to store information about clubs, events, and times. var clubName = {}; var event = {}; var time = {}; var dict = new Map(); dict.set(clubName, "G ...

Utilizing jQuery for cloning elements

I need to add functionality for adding and deleting rows in multiple tables on my website. Currently, I am doing this by directly inserting HTML code using jQuery, but it has become inefficient due to the number of tables I have. I am considering creating ...

How can you make each <li> in an HTML list have a unique color?

Looking for a way to assign different colors to each <li> element in HTML? <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <ul> Here's how you want them displayed: Item 1 should be red Ite ...

Learn the technique of invoking a sub component's method from the parent component in Vue.js

I am looking to trigger a method in a sub component from the parent component in Vue.js in order to refresh certain parts of the sub component. Below is an example showcasing what I aim to achieve. Home.vue <template> <componentp></compo ...

Passing information from the created hook to the mounted hook in VueJS

How can I transfer data from the created function to the mounted function in VueJS? In my VueJS application, the code in my created function is as follows: created: function(){ $.getJSON({ url: 'static/timeline.json', success:function( ...

What is the best way to access Firebase data within a Vue component?

I can view the data in the Vue console, but there's an issue showing up: 'Property or method "rsvp" is not defined on the instance but referenced during render.' What is the correct way to reference the firebase data? <template> ...

Incorporate text into the URL of the image

Got a URL of an image like this: https://lipsum.mobi/catalog/product/SE0229E/YG/AAA/4/1/SE0229E-YG-AAA-4.jpg', and looking to add 240x240 within the URL. Current Url: https://lipsum.mobi/catalog/product/SE0229E/YG/AAA/4/1/SE0229E-YG-AAA-4.jpg Desire ...