Overview

  • Load JavaScript Scheduler data (events and resources) from two different URLs and update the Scheduler once when both responses are available.

  • The sample project uses PHP backend.

License

Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.

Parallel HTTP Requests

If you make two HTTP request using fetch() (or any other HTTP request API) they will be executed in parallel (because they are asynchronous):

function loadData() {
  fetch("backend_events.php").then(response => response.json()).then(events => {
    dp.update({events});
  });
  fetch("backend_resources.php").then(response => response.json()).then(resources => {
    dp.update({resources});
  });
}

This solution will work but there are two problems:

  • It results in two update() calls which is ineffective (screen rendering is expensive).

  • You can’t rely on the HTTP requests to complete in the original order. In this case it might not be important - the Scheduler can update events and resources in any order. In other cases it may result in random and hard-to-reproduce errors.

Wait for All Requests to Complete

To solve this problem, you can use Promise.all() to wait for all requests to complete. This method will merge all promises passed as arguments and not resolve before all those promises are resolved.

In this example, the update() method will be called only once, when both responses (event and resource data) are available:

function loadData() {
  const start = dp.visibleStart();
  const end = dp.visibleEnd();

  const promiseEvents = fetch(`backend_events.php?start=${start}&end=${end}`).then(response => response.json());
  const promiseResources = fetch("backend_resources.php").then(response => response.json());

  Promise.all([promiseResources, promiseEvents]).then(values => {
    const [resources, events] = values;
    dp.update({
      resources,
      events
    });
    dp.message("Scheduler data loaded");
  });
}

Here is an asynchronous version of the same method (async/await):

async function loadDataAsync() {
  const start = dp.visibleStart();
  const end = dp.visibleEnd();

  const promiseEvents = fetch(`backend_events.php?start=${start}&end=${end}`).then(response => response.json());
  const promiseResources = fetch("backend_resources.php").then(response => response.json());

  const [resources, events] = await Promise.all([promiseResources, promiseEvents]);

  dp.update({
    resources,
    events
  });
  dp.message("Scheduler data loaded");
}

You can also use this method to load additional data that are needed during the Scheduler update.