One of my favorite JS challenges on Stack Overflow
Tags: javascript
Published: 2022-04-26 08:09:06

[This one](https://stackoverflow.com/questions/70439366/how-do-i-randomly-change-an-html-element-on-a-timer-using-javascript-across-th/70439907#) got me hooked for hours. I love when I find uncommon questions and have the time to attempt to solve them.

After one year and four months of been active on Stack Overflow and having answered almost 300 questions, this one is one of my favorite challenges. 

## The question

How does one randomly change an element across the board for all users without using a back-end ?

Well, to be honest the question was not exactly like that, the user wasn't discarding the use of a back-end but it just made it more interesting.

## How did I solve it?

The first time I read the question I thought it was not possible  without a back-end.

![Not possible](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ecexvcy1huyl9j0s2q6.gif)

But after some time thinking I realized that the key to unlock this mistery was in the value that [new  Date().getTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime) provides, due to the fact that returns a number that is the same across all computers around the world and is unique!

You can see the ⚙️ working snippet [here] (https://stackoverflow.com/questions/70439366/how-do-i-randomly-change-an-html-element-on-a-timer-using-javascript-across-th/70439907#70439907)

## Code explanation

First things first..

```html
<div id="root"/>
```

I retrieve the milliseconds since January 1, 1970 and then I convert it to hours:

```javascript
const hours = Math.round(new Date().getTime()/(1000*60*60))
```

Slice `hours` six digit number into three numbers and add them inside an array.

I'm creating this array with the purpose of having multiple unique numbers to create a random number depending on the time, which will be the same across all computers.

```javascript
const numbers = [
    Number(hours.toString().slice(0,2)),
    Number(hours.toString().slice(2,4)),
    Number(hours.toString().slice(4,6))
]
```

Now, I need images to display, depending on the random number that the code will generate. I get some URLs from [Lorem Picsum](https://picsum.photos/) and add them inside an array:

```javascript
images = [
    'https://picsum.photos/id/237/200/300', 
    'https://picsum.photos/id/236/200/300', 
    'https://picsum.photos/id/235/200/300',
    'https://picsum.photos/id/234/200/300',
    'https://picsum.photos/id/233/200/300',
    'https://picsum.photos/id/232/200/300',
    'https://picsum.photos/id/231/200/300',
    'https://picsum.photos/id/230/200/300',
    'https://picsum.photos/id/229/200/300',
    'https://picsum.photos/id/228/200/300'
  ];
```

Okay, is time to create the function that will return a random number by the hour.

### So how do we do it ? 

I'll show you step by step.. 

Inside `hourlyRand()` the first thing I build is an arrow function that will return a **pseudo random number** as a string depending on the `numbersArr` (array of numbers) passed to it.

This does not make much sense now 😵‍💫 but it will a few lines down the road. 

```javascript
function hourlyRand(){
  const pseudoRandString = (numbersArr) => {
    let rand = 1
    numbersArr.forEach((n, i) => {
      if(n !== 0) rand = rand * n 
    })
    return rand.toString()
  }  
}
```

Now using `pseudoRandString(numbersArr)` function I pass the `numbers` array initialized at the top like so `pseudoRandString(numbers)` and I assign the value to `randString` variable:

```javascript
  let randString = pseudoRandString(numbers)
```

By slicing the `randString` I can get a two digit number. But these numbers have a typeof `string` so I need to convert back to `Number` and assign the value to `n`:

```javascript
  // length of the pseudo random number string
  let L = randString.length

  let n = Number(randString.slice(L-3,L-1))
```

And the function `hourlyRand()` is almost ready. The only thing pending is to return `n`

The finished function `hourlyRand()` looks like so:

```javascript
function hourlyRand(){
  const pseudoRandString = (numbersArr) => {
    let rand = 1
    numbersArr.forEach((n, i) => {
      if(n !== 0) rand = rand * n 
    })
    return rand.toString()
  }  
  
  // get a pseudo random number and convert to string
  let randString = pseudoRandString(numbers)

  // length of the pseudo random number string
  let L = randString.length

  // slice the string and convert to number
  let n = Number(randString.slice(L-3,L-1))

  // return the double digit hourly random number
  return n
}
```

Now that we have all we need, we get the two digit random number from `hourlyRand()` and divided by 10 (because we have 10 images) and round it:

```javascript
// pseudo-random number between 0 and 9 
let n = Math.round(hourlyRand()/10)
```

Finally to display the hourly random image just add `n`  as an index of the images array:

```javascript
const element = document.getElementById('root')
element.innerHTML = '<img src=' + images[n] + '/>'
```