Update date and time when time is midnight

Viewed 338

I am working on react dashboard which is to be displayed on large TV. It works fine for a single day. But when time reaches midnight dashboard gets stuck on same day and won't roll over to next day.

My approach

import React from 'react'
import moment from "moment";

function UpdateDate() {

const [{ startDate, endDate }] = useStateValue();

    useEffect(() => {

        var daterollOver = setInterval(function () {
            var now = moment().format("HH:mm:ss");
            if (now === "00:00:00") {
                window.location.reload();
            }
        }, 1000);

        return () => {
            clearInterval(daterollOver);
        }
    }, [])

    var url=`http:domain/live-dashboard?from=${startDate}&to=${endDate}`;
    return (
      <div>
          <iframe
            className="embed-responsive-item"
            src={url}
      ></iframe>
        </div>
    )
}

export default UpdateDate;

I am using react context api to manage the state. Below is the section of the reducers.js which takes current time from moment.

import moment from "moment";

export const initialState = {
    startDate: moment().startOf("day").local();,
    endDate: moment().endOf("day").local();,
}

What would be the best option to refresh the page the at midnight which would update startDate & endDate and roll over to next day when time is midnight?

2 Answers

I don't see you using startDate or endDate from context in your setInterval, so don't see the relevance of that? It's hard to say what's not working for sure but I would suggest a slightly different approach. Rather than checking every second if the time is exactly midnight... instead, I would check if the time is PAST midnight (using >=), and then also store the last time the page was refreshed, maybe in localstorage. Then you will change your logic to: is it after midnight, and more than 8 hours (or 23 hours... w/e) have elapsed since the last page refresh? Refresh the page. Something like that.

I'm naive when it comes to React myself, but from my understanding, you can use the useState hook to get/store things there.

I'd get the difference between now and midnight (represented here as endOf("day").add(1, 'ms')), then just set a timeout for that long. Don't bother checking every second or every minute or every hour. You know how much time needs to elapse, let that elapse. The setTimeout function is not terribly accurate, but on these scales it doesn't really matter. I wouldn't even check; just refresh. In the highly unlikely event it's too early, it will recalculate the next timeout to be very quick and resolve itself.

Using a state variable as the src of the iframe will cause a rerender of the HTML when the url changes, but that's fine -- you were reloading the page previously, this is less destructive than that.

I'm not sure if this works; I didn't bother creating a sandbox. Try it out, see if it helps. If it doesn't, please do create a sandbox (jsFiddle, codepen, whatever) to show it not working.

import React from 'react'
import moment from "moment";

function UpdateDate() {
  function generateUrl() {
    return `http:domain/live-dashboard?from=${moment().startOf("day")}&to=${moment().endOf("day")}`;
  }
  const [url, setUrl] = useState(generateUrl());
  useEffect(() => {
    let lastTimeout = 0;
    let setupReload = function() {
      const timeUntilMidnight = moment().diff(moment().endOf("day").add(1, "ms"), "ms");
      return setTimeout(function() {
        setUrl(generateUrl());
        lastTimeout = setupReload();
      }, timeUntilMidnight);
    };

    lastTimeout = setupReload();
    return () => {
      clearInterval(lastTimeout);
    }
  }, []);

  return (
    <div>
      <iframe className="embed-responsive-item"
              src={ url }>
      </iframe>
    </div>
  );
}

export default UpdateDate;

Related