"Prev" / "Next" buttons for a circular list I have an array of strings and on click of the "NEXT" button it displays the next array item in a &lt;p&gt; tag while on click of the "PREV" button it displays the previous one. When it reaches to the end (beginning) it continues from the first (last) item.

I have had some hard time to find a way to get the right item index when PREV is clicked and this is what i could have come up with.

I've used a  modulo operator on decreasing array indices.  I would like to know if there is a better way of doing this. By the way ES6 syntax is just what I like so I am not interested in any ES5 compatibility improvements.



var message = ["dog", "cat", "bear", "penguin", "tiger", "eagle", "John Doe"],
        pel = document.getElementById("text"),
        idx = 0,
    getNext = e =&gt; pel.innerText = e.target.id == "right" ? message[idx = ++idx%message.length]
                                                          : message[idx = (message.length - (message.length - --idx)%message.length)%message.length];
document.getElementById("right").onclick = getNext;
document.getElementById("left").onclick = getNext;
&lt;!DOCTYPE html&gt;
&lt;html&gt;

  &lt;head&gt;
    &lt;link rel="stylesheet" href="style.css"&gt;
    &lt;script src="script.js" defer &gt;&lt;/script&gt;
  &lt;/head&gt;

  &lt;body&gt;
   &lt;p id="text"&gt;dog&lt;/p&gt;
   &lt;button id="left" style = "width: 50px; background-color:gold" onclick="getNext"&gt;PREV&lt;/button&gt;
   &lt;button id="right" style = "width: 50px; background-color:tomato" onclick="getNext"&gt;NEXT&lt;/button&gt;
  &lt;/body&gt;

&lt;/html&gt;
I recommend splitting up the work into one function that is pure and another one that has side-effects.



const resultBox = document.getElementById('result')
const messages = ["cat", "dog", "fish"];
const length = messages.length;

const getNextIdx = (idx = 0, length, direction) =&gt; {
   switch (direction) {
     case 'next': return (idx + 1) % length;
     case 'prev': return (idx == 0) &amp;&amp; length - 1 || idx - 1;
     default:     return idx;
   }
}

let idx; // idx is undefined, so getNextIdx will take 0 as default
const getNewIndexAndRender = (direction) =&gt; {
     idx = getNextIdx(idx, length, direction);
     result.innerHTML = messages[idx]
}

getNewIndexAndRender();
&lt;p id="result"&gt;&lt;/p&gt;
&lt;button onclick="getNewIndexAndRender('prev')"&gt;prev&lt;/button&gt;
&lt;button onclick="getNewIndexAndRender('next')"&gt;next&lt;/button&gt;




Note: getNextIdx is a pure function, which will never modify any value, it takes the arguments it needs and returns a new value, we pass into it the currentIdx, the lengthOfTheArray and an action which lets the function decide, what to do.