Utilizing Vue.js: Disabling button on image carousel when there is no "next" photo accessible

This is my initial experience with Vue. I am attempting to assemble a slideshow using an array of images. I have successfully managed to disable the "previous" button when the user reaches the beginning of the slideshow, but I am encountering difficulties in disabling the "next" button when at the last image of the presentation.

Below is the snippet of my code:

Vue.config.devtools = true
var app = new Vue({
  el: '#app',
  data: {
    title: 'Photo of the day!',
    description: '',
    images:   [
    {
      image: 'https://cdn.spacetelescope.org/archives/images/wallpaper2/heic1509a.jpg', date: '1/9/2019', title: 'Beautiful Milky Way'
    },
    {
      image: 'https://img.purch.com/w/660/aHR0cDovL3d3dy5zcGFjZS5jb20vaW1hZ2VzL2kvMDAwLzA2MS8wNzUvb3JpZ2luYWwvY2hhbmRyYS1uZ2M2MzU3LWNvbXBvc2l0ZS5qcGc=', date: '1/10/2019', title: 'Amazing Whirlpool Galaxy'
    },
    {
      image: 'https://icdn3.digitaltrends.com/image/space-engine-featured-510x0.jpg?ver=1', date: '1/11/2019', title: 'Wonderous Large Magellanic Cloud'
    },

  ],
    currentNumber: 0,
    photosAvailable: true,
  }, 
  methods: {
    next: function() {
      app.currentNumber += 1;
      if (app.currentNumber === app.images.length) {
        console.log('SERGIO')
        app.photosAvailable = false 
        return 
      }
    },
    previous: function() {
      app.photosAvailable = true
      return app.currentNumber -= 1
    }, 
  }
})
<!DOCTYPE html>
<html>
  <head>
    <link href="./styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Anaheim" rel="stylesheet">
    <meta charset="UTF-8">
    <title>NASA Photo Of The Day</title>
  </head>
  <body>
    <div id='app'>
      <section class='hero'>
      <h1 class='title'>{{ title }}</h1>
    </section>
    <section class='picture-area'>
      <div class='info'>
        <h2>{{ images[currentNumber].title }}</h2>
        <p v-bind='description'>{{ description }}</p>
        <img class='image-of-day' :src='images[currentNumber].image' />
        <p class='date'>{{ images[currentNumber].date }}</p>
        <button :disabled="!currentNumber" v-on:click="previous" class='backward'>previous</button>
        <button :disabled="!photosAvailable" v-on:click="next" :class="{disabledButton: !photosAvailable}" class='forward'>next</button>
      </div>
    </section>
    </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="26475e4f495566160817140816">[email protected]</a>/dist/axios.min.js"></script>
  <script src='./index.js'></script>
  </body>
</html>

Observing my Vue devtools, I noticed that the photosAvailable flag does transition to false, which should render the button disabled. However, this functionality seems to be malfunctioning.

I hope there's someone out there who can pinpoint my mistake, considering it's my first dive into Vue development.

Answer №1

Implementing a solution that addresses the areas requiring improvement in your current code is key for success.

  • To avoid errors caused by using app when it's undefined, replace it with this within your methods. Utilize this to access state or methods within your component.

  • For the status of the next and prev buttons, define isPrevPhotoAvailable and isNextPhotoAvailable methods under the computed property as they are derived from the value of currentNumber of the slide. This enables you to eliminate isPhotosAvailable from your state.

Vue.config.devtools = true
var app = new Vue({
  el: '#app',
  data: {
    title: 'Photo of the day!',
    description: '',
    images:   [
    {
      image: 'https://cdn.spacetelescope.org/archives/images/wallpaper2/heic1509a.jpg', date: '1/9/2019', title: 'Beautiful Milky Way'
    },
    {
      image: 'https://img.purch.com/w/660/aHR0cDovL3d3dy5zcGFjZS5jb20vaW1hZ2VzL2kvMDAwLzA2MS8wNzUvb3JpZ2luYWwvY2hhbmRyYS1uZ2M2MzU3LWNvbXBvc2l0ZS5qcGc=', date: '1/10/2019', title: 'Amazing Whirlpool Galaxy'
    },
    {
      image: 'https://icdn3.digitaltrends.com/image/space-engine-featured-510x0.jpg?ver=1', date: '1/11/2019', title: 'Wonderous Large Magellanic Cloud'
    },

  ],
    currentNumber: 0
  }, 
  computed: {
    isNextPhotoAvailable: function() {
      return this.currentNumber + 1  !== this.images.length;
    },
    isPrevPhotoAvailable: function() {
      return this.currentNumber - 1  !== -1;
    }
  },
  methods: {
    next: function() {
      this.currentNumber += 1;
    },
    previous: function() {
      return this.currentNumber -= 1;
    }, 
  }
})
<!DOCTYPE html>
<html>
  <head>
    <link href="./styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Anaheim" rel="stylesheet">
    <meta charset="UTF-8">
    <title>NASA Photo Of The Day</title>
  </head>
  <body>
    <div id='app'>
      <section class='hero'>
      <h1 class='title'>{{ title }}</h1>
    </section>
    <section class='picture-area'>
      <div class='info'>
        <h2>{{ images[currentNumber].title }}</h2>
        <p v-bind='description'>{{ description }}</p>
        <img class='image-of-day' :src='images[currentNumber].image' />
        <p class='date'>{{ images[currentNumber].date }}</p>
        <button :disabled="!isPrevPhotoAvailable" v-on:click="previous" class='backward'>previous</button>
        <button :disabled="!isNextPhotoAvailable" v-on:click="next" :class="{disabledButton: !isNextPhotoAvailable}" class='forward'>next</button>
      </div>
    </section>
    </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="68091001071b285846595a4658">[email protected]</a>/dist/axios.min.js"></script>
  <script src='./index.js'></script>
  </body>
</html>

Answer №2

You could consider moving the logic to a computed property for improved organization and efficiency.

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

Receiving undefined properties in functional React components

Is it possible to pass the {requests} prop to the RequestRow component correctly, especially after the setRequests function is executed? The issue seems to be that when requests are initialized as undefined initially and then set with an asynchronously cal ...

Transform them into async/await in JavaScript

Exploring the promise-retry library, I discovered the following syntax: promiseRetry(function (retry, number) { return doSomething() .catch(retry); }) .then(function (value) { // .. }, function (err) { // .. }); Since I am utilizing a ...

JavaScript Calculator experiencing difficulty with adding two numbers together

I've been working on developing a calculator using HTML and JavaScript, but I'm facing an issue when trying to add two numbers together. Strangely enough, when attempting to calculate 1 + 0, I get the result of 512, and for 1 + 1, it returns 1024 ...

Searching for a deeply nested JSON property with lodash

I am dealing with a JSON API response that has the following structure: [ { title: "top1", sections: [ { section_title: "section1", content: [ { content_title: "title1", content_id: "id1" ...

What is the reason for jquery requiring _$ when overwriting?

var // Optimizing references to window and allowing renaming window = this, // Increasing efficiency in referencing undefined and enabling renaming undefined, // Creating aliases in case of jQuery overwrite _jQuery = window.jQuery, // Creating aliases in ...

The error stating that document.getElementById(...) is null has occurred within RSForms due to a TypeError

Issue: When clicking on the form to continue, a TypeError: document.getElementById(...) is null error occurs. Can anyone help me fix this problem? When I click on the continue button, it calls the function submitForm. <script type="text/javascript"> ...

Using the concept of method chaining in JavaScript, you can easily add multiple methods from

Hey there! I'm looking for some assistance with dynamically building a method chain. It seems like it should be pretty straightforward if you're familiar with how to do it... Currently, I am using mongoose and node.js to query a mongo database. ...

Issue encountered when attempting to invoke server-side function using JavaScript

[WebMethod] public static string simple() { Home h = new Home(); h.logout(); return "dfdsf"; } public void logout() { Response.Redirect(Config.Value("logout")); } client side code $('#logout').on('click', function () ...

Display tooltip information based on dynamic content

Can the q-tooltip text be loaded dynamically? Which property should be used for this purpose? In my scenario, which property should replace :value (please note that this is just a demonstration and not an actual property of q-tooltip)? <q-item-sectio ...

Using a Vue computed method to compare elements in two separate arrays

Presently, I am utilizing Vue v2.x.x and dealing with an array: sectionTitles = ['Technology', 'Data', 'Poverty and Research', ...] Additionally, I have jobsData structured like this: [{'title': 'Software Engin ...

How can I dynamically assign ngModel in AngularJS?

I've created a directive with an isolate scope that maps a list of objects to inputs for modifying a specific property. However, I now aim to make this component more universal by allowing it to bind to deeply nested properties within each object. Fo ...

Unable to append a property to each object within an array during a loop

Hey everyone, I could really use some help with this problem I'm facing. Let me explain what's going on - I'm working on pulling documents from MongoDB using Mongoose. Take a look at the array of objects that is returned from the mongoose qu ...

Avoiding page refresh while utilizing the ng5-slider component in Angular

I am currently working with an ng5-slider that has a customizable range from 0 to 1000. However, I have encountered an issue when adjusting the slider at the bottom of the page - it refreshes and automatically takes me back to the top of the page. I would ...

Dealing with side effects in react/redux: Best practices and tips

Trying to find the best way to integrate an async side-effects handler into my react/redux setup has been quite a challenge. In my react-router-driven application, all the main containers at root level are smoothly dispatching actions and receiving update ...

Navigation Menu in Motion

I'm currently working on a website for my F1 in Schools team and I'm looking to implement a feature where the button in the navigation bar changes its background color and font color when that section of the page is active, even while scrolling o ...

Is there a way for me to store the output of an AJAX call?

One of the challenges I'm facing involves an AJAX request: $.ajax({ url: 'script.php?val1=' + value1 + '&val2=' + value2, dataType: "json", success: function (data) { var newValue1 = data[0]; ...

Is it possible to incorporate both Matter and Arcade physics into the Player object?

I attempted to instantiate a player object export default class Player extends Phaser.Physics.Matter.Sprite { constructor(data) { let { scene, x, y, texture, frame } = data; super(scene.matter.world, x, y, texture, frame); this. ...

Looking for a way to limit the number of characters allowed per line in a textarea using jQuery

I have the following HTML textarea: <textarea name="splitRepComments" cols="20" rows="3" ></textarea> I have implemented a maxlength restriction using jQuery with the following function: var max = 100; $('#splitRepComments').bind(" ...

How can I monitor database changes in Laravel using Vue.js?

I'm looking for a solution to automatically update data in VueJS when there are changes in the database without requiring the user to refresh the page. For example, if a user visits my website and sees that the name of the first user is Alex, but then ...

Using JavaScript to submit the value of a checkbox

I'm currently working on a form submission using JavaScript that includes both text input and two checkboxes. <script> function SubmitFormData() { var preferredLocation = $("#preferred_location").val(); var relocation = []; ...