Creating a Countdown Timer

In this tutorial we will walk through how to use the Current Service query of our public API to implement a countdown timer on your church website.

📘

This tutorial will use vanilla HTML and Javascript to interact with our API. Contact our Support Team at support.online.church if there additional examples you would like to see.

To query for the current or upcoming service, our query will need to select the id, startTime, endTime and content.title:

const CURRENT_SERVICE_QUERY = `
  query CurrentService {
    currentService(onEmpty: LOAD_NEXT) {
      id
      startTime
      endTime
      content {
        title
      }
    }
  }
`;

Using this query, we will make a POST request to the /graphql path of your church URL using fetch. Both the Content-Type and Accept headers are required to be set, and the query should be passed in the query property of the body of the request.

const service = await fetch('https://subdomain.online.church/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify({
    query: CURRENT_SERVICE_QUERY,
    operationName: 'CurrentService',
  })
})
.then(response => response.json());

📘

After parsing the response of a GraphQL request, the resulting data will be under a data.${queryName} property. For example:

{
  "data":{
    "currentService":{
      "id":"457457ba-16a9-44bc-a54e-4b8b8e66b163",
      "startTime":"2020-10-02T14:26:00Z",
      "endTime":"2020-10-02T15:26:00Z",
      "content":{
        "title":"Mastermind Week One"
      }
    }
  }
}

Now that we have the response we can use the data to populate a countdown timer. Here is an example of how you could implement the required logic.

// If a service was not returned from the API, don't display the countdown
if (!service.data.currentService || !service.data.currentService.id) {
  return;
}

// Set the service title
document.getElementById('serviceTitle').innerText = service.data.currentService.content.title;

// Set the date we're counting down to
const startTime = new Date(service.data.currentService.startTime).getTime();
const endTime = new Date(service.data.currentService.endTime).getTime();

// Create a one second interval to tick down to the startTime
const intervalId = setInterval(function() {
  const now = new Date().getTime();

  // If we are between the start and end time, the service is live
  if (now >= startTime && now <= endTime) {
    clearInterval(intervalId);
    document.getElementById('countdown').innerHTML = 'Live';
    return;
  }

  // Find the difference between now and the start time
  const difference = startTime - now;

  // Time calculations for days, hours, minutes and seconds
  const days = Math.floor(difference / (1000 * 60 * 60 * 24));
  const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((difference % (1000 * 60)) / 1000);

  // Display the results in the element with id="countdown"
  document.getElementById("countdown").innerHTML = days + "d " + hours + "h "
    + minutes + "m " + seconds + "s ";

  // If we are past the end time, clear the countdown
  if (difference < 0) {
    clearInterval(intervalId);
    document.getElementById('countdown').innerHTML = '';
    return;
  }
}, 1000);

With the functionality of the countdown timer working, all that remains is to apply styling to the timer to match your website. For a working example you can reference this Codesandbox: