Lattice Grid Buy a licence

demo D06

Loading data after the grid exists in Angular

An empty grid that fills from a fetch, with the loading state between

rows.load(data)

This grid is created empty and then filled from a fetch, showing the loading state in between. It matches how most apps really work, the shell renders first and the rows arrive a moment later, so you can build the grid before the data exists and drop it in when it lands.

Building…
Loading a live grid…

This is the Angular version. A standalone component takes the whole configuration through one config input, surfaces grid events as outputs, and exposes the live grid on a getter for anything the inputs do not cover.

The configuration

import { Component, ViewChild, OnDestroy } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { LatticeGridComponent, provideLattice } from '@toclocoinc/lattice-grid/angular';

const columns = [
  { field: 'circuit', title: 'Circuit', layout: { width: 180 } },
  { field: 'region', title: 'Region' },
  { field: 'status', title: 'Status', filter: { type: 'set' } },
  { field: 'bandwidth', title: 'Bandwidth', type: 'number' },
  { field: 'charge', title: 'Monthly charge', type: 'number',
    format: { style: 'currency', currency: 'GBP' } },
];

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [LatticeGridComponent],
  template: '<lattice-grid [config]="grid" (grid-ready)="onGridReady()" style="display:block;height:540px"></lattice-grid>',
})
export class AppComponent implements OnDestroy {
  @ViewChild(LatticeGridComponent) gridRef!: LatticeGridComponent;
  private live = true;

  grid = {
    rowKey: 'id',
    columns,
    rows: [] as any[],
  };

  // Mount empty, then hand the grid its rows once the fetch resolves. The empty
  // state shows until rows.load() is called, and the grid repaints in place
  // after, with no rebuild. The grid is created once the view has rendered,
  // so the live instance arrives on grid-ready rather than in ngAfterViewInit.
  onGridReady() {
    fetch('/api/circuits')
      .then((r) => r.json())
      .then((rows) => { if (this.live) this.gridRef.grid.rows.load(rows); });
  }

  ngOnDestroy() { this.live = false; }
}

bootstrapApplication(AppComponent, {
  providers: [provideLattice({ createGrid })],
});

Populating a grid after it mounts

Most integrations construct the grid before the data exists: a dashboard shell renders, an API call goes out, and the rows arrive some milliseconds later. Lattice Grid separates these two moments deliberately. createGrid builds the columns, the header and the empty body immediately, and rows.load(data) fills it whenever the fetch resolves, without a second construction step or a full remount. This is the shape a JavaScript data grid needs for any screen backed by a remote call, a websocket handshake, or a route that streams from a loader before its data dependency settles.

Between construction and the load call, the grid shows a loading state rather than an empty table with no explanation, so the viewer sees a grid that is working rather than one that has failed to render. Once rows.load runs, the body populates in place: scroll position, column widths and any sort or filter already configured on the grid all carry over, because the grid was never torn down to receive its data.

The same call handles a refresh, not only the first load. Calling rows.load again replaces the row set cleanly, which makes it the entry point for both the initial fetch and any subsequent reload triggered by the host application.

How do you show a loading state before a data grid has data?

Construct the grid immediately with createGrid(el, { columns, rows: [] }), so the header and empty body render before the fetch completes. Lattice Grid displays a built-in loading state for the empty body automatically; when the request resolves, call rows.load(data) to fill it, and the same call works again for any later refresh.