You are viewing documentation for Vaadin Framework 8 and related products View documentation for Vaadin Framework 7 ›
Lazy Loading and Remote Data · Vaadin
Vaadin Elements - Grid - Lazy Loading and Remote Data

Lazy Loading and Remote Data

In this section, you will learn how to use functions as data sources. This enables you to use lazy loading and remote data, such as with REST APIs.

Function Data Source

In addition to assigning an array to the items property, you can alternatively assign a function. The vaadin-grid element calls this function lazily, only when it needs more data to be displayed.

The function takes two parameters: a params object and a callback function. The params object provides index and count properties, expressing the starting index from which data should be returned, and how many items should be returned, respectively.

The callback parameter is a callback function which you must call with an array of the requested items as a parameter.

var employees = [
  {
    user: {
      name: { first: 'amber', last: 'crawford' },
      email: '[email protected]'
    }
  },
  {
    user: {
      name: { first: 'zoe', last: 'caldwell' },
      email: '[email protected]'
    }
  },
  {
    user: {
      name: { first: 'jessie', last: 'brooks' },
      email: '[email protected]'
    }
  }
  ...
];

grid.size = employees.length;
grid.items = function(params, callback) {
  callback(employees.slice(params.index, params.index + params.count));
};

When using function data sources, size always needs to be set manually. You can set it once, as was done in the example above, or alternatively as a second parameter given to the callback function.

callback(employees.slice(params.index, params.index + params.count), employees.length);

For more details, see the API Documentation https://cdn.vaadin.com/vaadin-core-elements/latest/vaadin-grid/

See the live example.

Remote Data

Using remote data does not differ much from using arrays within a function data source. You just need make sure you are handing an array of data over to the callback function.

The index and count properties from the params argument come in handy if you are using a REST API that supports fetching partial result sets.

grid.items = function(params, callback) {
  var url = 'https://my.data/data?index=' + params.index + '&count=' + params.count;
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
      var response = JSON.parse(xhr.responseText);
      callback(response.employees);
    }
  };

  xhr.open('GET', url, true);
  xhr.send();
};

Defining the Data Set Size

In most cases when using remote data, you cannot know the size of the data set in advance. In the following are a few examples how you could set the size in different scenarios.

  • There is a separate API for fetching the size.

    // Define a function that you call manually every time
    // you believe the size might've changed.
    function setSize() {
      var url = 'https://my.data/size';
      var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
          if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
            grid.size = JSON.parse(xhr.responseText).totalSize);
          }
        };
        xhr.open('GET', url, true);
        xhr.send();
      };
    }
  • The size is delivered with the data payload.

    grid.items = function(params, callback) {
      var url = 'https://my.data/data?index=' + params.index + '&count=' + params.count;
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
          var response = JSON.parse(xhr.responseText);
          callback(response.employees);
    
          // Assign size from the data payload.
          grid.size = response.totalSize;
        }
      };
    
      xhr.open('GET', url, true);
      xhr.send();
    };
  • There is no API for getting the total size at all.

    // Set an initial size.
    grid.size = 10;
    
    grid.items = function(params, callback) {
      var url = 'https://my.data/data?index=' + params.index + '&count=' + params.count;
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
          var response = JSON.parse(xhr.responseText);
          callback(response.employees);
    
          // Increase the size dynamically, resulting in "infinite" scrolling.
          if (params.index + params.count == grid.size) {
            grid.size += 10;
          }
        }
      };
    
      xhr.open('GET', url, true);
      xhr.send();
    };

See the live example.