Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React / Javascript for loop - Start from idx 0 when exceeding array length

i hope one of you are able to help me with a javascript / react question. I am building a web application where you as a user can create setlists with lyric id's inside. This means that when opening a setlist, you can view each and every lyric referenced inside that setlist. At the bottom of the window i have a previous and next button that allows you to view the next or the previous lyric from the list.

My problem is that when reaching the end / last index number of the lyrics list and i try to click next, the for loop breaks and my page is crashing. What i want it to do is that when the length of the lyrics array has been reached and you try to exceed, then the for loop restarts from index 0 again. I have tried multiple things and theories but i cannot seem to find anything that is working.

This is the array of lyric id's i have.

['Id1', 'Id2', 'Id3', 'Id4']

Here is my function to check for the current index number / Which lyric id that is being viewed right now. This function is returning the current index number.

function checkLyricIdx() {
        let setlistLength = setlist.lyrics.length;
        for (var i = 0; i < setlistLength; i++) {
            if (setlist.lyrics[i] === chosenLyricId) {
                return i;
            }
        }
 }

Here is the "View next lyric" function that first checks for the current index number and then updates the state with the next lyric id (Doing that by increasing the idx number).

async function viewNextLyric(e) {
        e.preventDefault();
        let currentIndex = await checkLyricIdx();
        setChosenLyricId(setlist.lyrics[currentIndex + 1]);
    }

The function for viewing the previous lyric id is almost the same as above, i just minus 1 to the currentIndex.

Just to clarify my question. How can i redo this function so that it won't break when exceeding the length of the array? I want it so that when trying to exceed the length of the array then it restarts to index 0 / you view the list all over again. When i reach the last lyric id and i try to click next, the application crash and says the following:

TypeError: undefined is not an object (evaluating 'chosenLyricId.length')

like image 309
Michael Ørregaard Andersen Avatar asked Dec 09 '25 21:12

Michael Ørregaard Andersen


1 Answers

Use a modulus operation if you want the index to wrap from either end.

const dataArray = ['id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7'];

const wrapIndex = (arr, index) => index % arr.length;

for (let i = 0; i < 50; i++) {
  console.log('Iteration', i, 'index', wrapIndex(dataArray, i), dataArray[wrapIndex(dataArray, i)]);
}

You can also bound it if you want.

const dataArray = ['id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7'];

const bound = (min, max, val) => Math.max(min, Math.min(val, max));

const boundIndex = (arr, index) => bound(0, arr.length - 1, index);

for (i = -3; i < 10; i++) {
  console.log('Iteration', i, 'index', boundIndex(dataArray, i), dataArray[boundIndex(dataArray, i)]);
}
like image 156
Drew Reese Avatar answered Dec 12 '25 11:12

Drew Reese