The dashboard, as an object model

Enumerate everything the dashboard contains from JavaScript — worksheets, zones, size — and never hard-code a sheet name you could have discovered.

beginner6 min1 step

Why it matters

Every real extension starts with the same question: what am I sitting inside of? dashboardContent.dashboard is the root of the entire API — worksheets hang off it, objects (every zone on the canvas, including you) hang off it, parameters are one call away. The habit to build is enumerate, don't hard-code: an extension that discovers its worksheets keeps working when someone renames Sheet 1, and an extension that must target one specific sheet should prove that sheet exists and fail with a sentence, not a stack trace.

Prompt Recipe

Write the JavaScript for a Tableau dashboard extension that, after tableau.extensions.initializeAsync() resolves, renders an inventory of its host dashboard into the page: the dashboard name and size, then every worksheet by name, then every dashboard object with its type (blank, text, image, web-page, extension, worksheet) and name. Build the DOM with plain document.createElement — no frameworks. If a worksheet named in a WATCHED_SHEET constant is missing, show a one-line warning that names the sheets that do exist.

Three collections cover the canvas. dashboard.worksheets is the one you will use constantly — every viz on the dashboard, each a full Worksheet object whose data, filters, and events the rest of this wall is about. dashboard.objects is every zone — worksheets again, but also text boxes, images, blanks, and your own extension, each with a type, name, position and size. dashboard.size is the canvas itself.

Everything here is a property read, not a network call — the object model is handed to you at initialization, so walking it is free.

javascript
(async () => {
  await tableau.extensions.initializeAsync();
  const dashboard = tableau.extensions.dashboardContent.dashboard;

  console.log('dashboard:', dashboard.name,
              dashboard.size.width + 'x' + dashboard.size.height);

  // The vizzes — the objects the rest of this wall works with.
  for (const ws of dashboard.worksheets) {
    console.log('worksheet:', ws.name);
  }

  // Every zone on the canvas, your own extension included.
  for (const obj of dashboard.objects) {
    console.log('object:', obj.type, '-', obj.name);
  }

  // Enumerate, then verify — never assume a sheet name.
  const WATCHED_SHEET = 'Sales by Region';
  const target = dashboard.worksheets.find(w => w.name === WATCHED_SHEET);
  if (!target) {
    console.warn('No worksheet named "' + WATCHED_SHEET + '". Found: ' +
                 dashboard.worksheets.map(w => w.name).join(', '));
  }
})();

Got what you came for? Mark the stop and the line fills in beneath you.