VueJS Array Index causing unexpected output

I have been developing a unique poetry application that pulls in poetry using an API call.

To fetch the data, I am utilizing the axios library and using v-for to render the data. The index from v-for is used to load the image for each respective poem.

My pagination system displays 10 results per page with a custom next button feature for now.

However, I encountered an issue when navigating to Page 2. Since I rely on the v-for index to display images, it doesn't update when moving to the next page, resulting in the same images being displayed as on Page 1.

Code:

new Vue({
  el: '#app',
  data: {
    proxy: 'https://cors-anywhere.herokuapp.com/',
    imageIndex: 0,
    pagination: {
      start: 0,
      end: 10,
      resPerPage: 10
    },
    fetchData: [],
    fetchImages: []
  },
  methods: {
    paginate() {
      this.pagination.start = this.pagination.start + this.pagination.resPerPage;
      this.pagination.end = this.pagination.end + this.pagination.resPerPage;
    },
    async fetchDatas() {
      try {
        const res = await axios(`${this.proxy}http://poetrydb.org/author,title/Shakespeare;Sonnet`);
        if (res) {
          this.fetchData = res.data;
        }
      } catch (error) {
        console.log(error);
      }
    },
    async fetchImagess() {
      const key = '9520054-7cf775cfe7a0d903224a0f896';
      const perPage = 154;
      const proxy = ''
      const res = await axios(`${this.proxy}https://pixabay.com/api/?key=${key}&per_page=${perPage}`);
      this.fetchImages = res.data.hits;
    }
  },
  mounted() {
    this.fetchDatas();
    this.fetchImagess();
  }
});
<div id="app">
  <div v-for="(poetry, index) in fetchData.slice(this.pagination.start, this.pagination.end)">
    <div>
      <img :src="fetchImages[index].largeImageURL.toLowerCase()" style="max-width: 100%;height: auto;max-height: 320px;">
      <div>
        <h5>{{ poetry.title }}</h5>
        <span v-for="(poetryBody, i) in poetry.lines.slice(0, 5)">
              {{ i === 4 ? poetryBody.split(',').join('') + '...' : poetryBody  }}
            </span>
        <br>
        <a href="#">Read More</a>
      </div>
    </div>
  </div>
  <nav style="padding-top: 3em;">
    <button @click="paginate()">Next</button>
  </nav>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>

JSFiddle: http://jsfiddle.net/sanjaybanjade/vnu654gk/9/

It's clear that the images are not updating correctly when moving to Page 2. Any assistance in resolving this issue would be greatly appreciated!

Also, please disregard the console errors, as they will be addressed at a later stage.

Answer №1

An immediate solution is to determine the offset in line 4 for pagination updating:

<img v-bind:src="fetchImages[index + pagination.start].largeImageURL.toLowerCase()" style="max-width: 100%;height: auto;max-height: 320px;">

Answer №2

Incorrect at this particular line

fetchImages[index].largeImageURL.toLowerCase()
.

The issue arises from the fact that you are iterating through a sliced array of fetchData, meaning the index pertains to the sliced array and not the original one. To resolve this, it is necessary to implement pagination slicing for your fetchImages as well.

Answer №3

Executing the fetchData.slice() method will result in a fresh object being produced. Therefore, even if you extract 10 new poems using slice, their indexes will remain from 0 to 9 because the returned object contains only that number of items each time.

Answer №4

The reason it isn't functioning properly is because you are only slicing fetchData in this line of code:

fetchData.slice(this.pagination.start, this.pagination.end)
. However, you are not slicing the fetchImages, which means that the fetchImages array remains unchanged, resulting in index 0 still referring to the same image. It would be best to ensure they are synchronized by creating separate arrays for pageData and pageImages, updating both every time the paging changes with a method like updatePageData.

new Vue ({
  el: '#app',
  data: {
      proxy: 'https://cors-anywhere.herokuapp.com/',
      imageIndex: 0,
      pagination: {
        start: 0,
        end: 10,
        resPerPage: 10
      },
      fetchData: [],
      fetchImages: [],
      pageData: [],
      pageImages: []
  },
  methods: {
    paginateNext() {
      this.pagination.start = this.pagination.start + this.pagination.resPerPage;
      this.pagination.end = this.pagination.end + this.pagination.resPerPage;
      this.updatePageData()
    },
    updatePageData () {
    this.pageData = this.fetchData.slice(this.pagination.start, this.pagination.end)
      this.pageImages = this.fetchImages.slice(this.pagination.start, this.pagination.end)
    },
    async fetchDatas() {
      try {       
        const res = await axios(`${this.proxy}http://poetrydb.org/author,title/Shakespeare;Sonnet`);
        if(res) {
          this.fetchData = res.data;
        }
      } catch(error) {
        console.log(error);
      }
    },
    async fetchImagess() {
      const key = '9520054-7cf775cfe7a0d903224a0f896';
      const perPage = 154;
      const proxy = ''
      const res = await axios(`${this.proxy}https://pixabay.com/api/?key=${key}&per_page=${perPage}`);
      this.fetchImages = res.data.hits;
    }
  },
  mounted() {
  Promise.all([
    this.fetchDatas(),
      this.fetchImagess()
    ])
    .then(() => this.updatePageData())
  }
});
<div id="app">
  <div v-for="(poetry, index) in pageData">
    <div>
      <img :src="pageImages[index].largeImageURL.toLowerCase()" style="max-width: 100%;height: auto;max-height: 320px;">
      <div>
        <h5>{{ poetry.title }}</h5>
        <span v-for="(poetryBody, i) in poetry.lines.slice(0, 5)">
              {{ i === 4 ? poetryBody.split(',').join('') + '...' : poetryBody  }}
            </span>
        <br>
        <a href="#">Read More</a>
      </div>
    </div>
  </div>
  <nav style="padding-top: 3em;">
    <button @click="paginateNext()">Next</button>
  </nav>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>

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

How to reposition the Bootstrap navbar Logo from the left to the center

I am looking to change the ordering of Bootstrap 4 Navbar. Currently, the logo is on the left side, but I want it in the center with menus on both sides. Can someone help me with changing this order? Check out the current Navbar layout below: <nav c ...

Struggling with inserting a fresh form into every additional <div> section

During my quest to develop a To-Do list application, I encountered a new challenge. In my current implementation, every time a user clicks on New Category, a new div is supposed to appear with a custom name and a specific number of forms. However, an issu ...

Resetting forms in AngularJS 1.5.6 with ng-messages functionality

I have been searching for solutions on Stackoverflow regarding how to reset a form, but I am still not able to figure it out. Even though the input was valid, the error message kept showing up. Upon debugging the application, I noticed that the message was ...

Is it possible to use nodemailer locally with NodeJS? The issue is that the greeting emails are not being received

Every time I attempt to send an email using nodemailer within my local network, I encounter the following error: *Greeting never received at SMTPConnection._formatError (C:\Users\PI_TEAM\Desktop\node_modules\nodemailer\lib ...

Issue with Navigation Scrolling Feature on Wordpress

I am in the process of implementing a 'scroll-nav' for my website. To achieve this, I decided to separate the Navigation into two sections and incorporate some jQuery: <nav class="main-nav clearfix"> <?php wp_nav_menu(array('th ...

Using JavaScript's DOM manipulation to switch out one HTML tag for another

As a newbie to javascript and DOM, I'm facing an issue with manipulating DOM elements using javascript in the given HTML code. <html> <head> <title>Testing</title> </head> <body> <marquee direction=up heig ...

Issue with Submit Event in React - Enter Key Fails to Trigger

I'm currently experimenting with a small front-end react project that's using Soundcloud's API. The project is quite basic at the moment - it takes user input and queries the API for related songs. I've encountered an issue where the en ...

Is there a way to reverse the hover effect on div elements?

Let's start by examining the code I've written: HTML: <div class="button_container"> <div class="inner_button"> <a href="#" class="button_text">Button</a> </div> <div class="button_side"> ...

Maximizing Input Field Utility in React JS

I have a challenge with retrieving values from the input field and passing it to the useEffect. I specifically want the search to be triggered only after pressing the onSearch function. The issue is that I can only capture the value using the onChange func ...

Error: The property '...' is not found in the ReactElement<any, any> type, but it is required in the type '{...}'

As a beginner in TypeScript, I am currently working on rendering a page by fetching data from getStaticProps. The code snippet I am using for this purpose is: import React, {FormEvent, useState} from "react"; import { InferGetStaticPropsType } fr ...

Exploring the World of GiantBomb APIs

I have successfully created an account and obtained my API key. I am looking to implement a basic search functionality on my webpage, where users can enter a search query and click a button to display the game title and image. You can find more informatio ...

Exploring time differences in Javascript

I am trying to save a JSON AJAX response from the server in the browser's localStorage for a duration of one minute, along with a timestamp generated using new Date().getMinutes(). Upon triggering $(document).ready, I aim to check the stored timestam ...

In search of a resolution for the error message "multipart: NextPart: bufio: buffer full" while attempting to upload an image via a fetch post request. Can anyone provide guidance

What steps can be taken to resolve the issue "multipart: NextPart: bufio: buffer full" when using a fetch post request to upload an image? I have a feature on my website that allows users to upload profile pictures. I use a fetch post request for this pur ...

The price filter slider is experiencing issues with the onresize function not functioning properly

I am facing an issue with a price filter I developed for my project. Despite having coded it, the filter is not functioning properly. <div class="price_range_caption"> <span class="currency_from">Rs.</span><span id="price_range_f ...

How can I use jQuery to pinpoint where my focus currently lies and debug any issues?

Triggering focus() on an element is a simple task, but after encountering debugging problems, I've come to realize that finding out where my focus has shifted can be quite challenging. The issue arises when I'm creating a modal window using jq.UI ...

When incorporating Vue as an npm package, a Vue 3 app may inadvertently clear the mounted element upon initialization

I have a straightforward Vue 3 application that is working perfectly fine when I include Vue as a script, as shown in the code snippet below. However, I need to integrate it with webpack by including it as an npm package. When I do this, the app loads but ...

Why would you need multiple root handlers?

One interesting feature to note is that multiple callback functions can be used as middleware to handle a request. These callbacks can take on different forms - they could be in the form of a single function, an array of functions, or even a combination of ...

A JSON request is being processed within a while loop

Attempting to complete what I initially thought was a simple task has led me to believe that I may have oversimplified the process or made a mistake in my loop. My objective is to browse through a series of links containing JSON objects in order to identif ...

When using a set of checkboxes, ensure that only one can be selected at any given time

My objective is to have a group of check boxes on a page where only one can be selected at a time. I want the checked box to clear any other selections when clicked. I attempted to implement this functionality in a fiddle, but it does not work as expected. ...

Instructions for implementing tooltips on a pie chart slice when hovering with the mouse pointer, using the canvas

var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var cw = canvas.width; var ch = canvas.height; ctx.lineWidth = 2; ctx.font = '14px verdana'; var PI2 = Math.PI * 2; var myColor = ["Gr ...