Working with Apps

Learn how to access and manipulate Qlik applications, sheets, and objects using the TypeScript SDK.

Getting Applications

List Available Apps

Retrieve all applications accessible to the authenticated user

typescript
// Get all available apps
const apps = await qlik.getAppList();

console.log(`Found ${apps.length} applications:`);
apps.forEach(app => {
  console.log(`- ${app.name} (ID: ${app.id})`);
  console.log(`  Published: ${app.published}`);
  console.log(`  Owner: ${app.owner.name}`);
});

// Filter published apps only
const publishedApps = apps.filter(app => app.published);

// Find specific app by name
const salesApp = apps.find(app => 
  app.name.toLowerCase().includes('sales')
);

App Object Properties

id: string - Unique application identifier
name: string - Application display name
description?: string - Optional app description
published: boolean - Whether app is published
publishTime?: string - When the app was published
owner: { id: string, name: string } - App owner information

Opening Applications

Open App by ID

typescript
// Open a specific app by ID
const appId = 'your-app-id-here';
const app = await qlik.getApp(appId);

console.log('App opened successfully');

// Now you can work with the app
const sheets = await app.getSheets();
console.log(`App has ${sheets.length} sheets`);

Open App with Error Handling

typescript
async function openAppSafely(appId: string) {
  try {
    const app = await qlik.getApp(appId);
    console.log(`✅ Successfully opened app: ${appId}`);
    return app;
  } catch (error) {
    if (error.code === 'APP_NOT_FOUND') {
      console.error('❌ App not found or no access');
    } else if (error.code === 'AUTHENTICATION_REQUIRED') {
      console.error('❌ Authentication required');
      await qlik.authenticateToQlik();
      // Retry after authentication
      return await qlik.getApp(appId);
    } else {
      console.error('❌ Unexpected error:', error.message);
    }
    throw error;
  }
}

Working with Sheets

Getting Sheets

typescript
// Get all sheets in an app
const sheets = await app.getSheets();

console.log(`Found ${sheets.length} sheets:`);
sheets.forEach(sheet => {
  console.log(`- ${sheet.title} (ID: ${sheet.id})`);
  console.log(`  Description: ${sheet.description || 'No description'}`);
  console.log(`  Rank: ${sheet.rank}`);
});

// Find specific sheet
const dashboardSheet = sheets.find(sheet => 
  sheet.title.toLowerCase().includes('dashboard')
);

if (dashboardSheet) {
  console.log('Found dashboard sheet:', dashboardSheet.title);
}

Sheet Operations

typescript
// Get a specific sheet by ID
const sheet = await app.getSheet('sheet-id');

// Get all objects in the sheet
const objects = await sheet.getObjects();
console.log(`Sheet has ${objects.length} objects`);

// Get sheet properties
const layout = await sheet.getLayout();
console.log('Sheet layout:', layout);

// Make selections on the sheet
await sheet.clearSelections();
await sheet.selectValues('Product', ['Laptop', 'Phone']);

// Export sheet as image (if supported)
const imageUrl = await sheet.exportImg();
console.log('Sheet image URL:', imageUrl);

Working with Objects

Getting and Manipulating Objects

typescript
// Get a specific object by ID
const object = await app.getObject('object-id');

// Get object data
const layout = await object.getLayout();
console.log('Object type:', layout.qInfo.qType);
console.log('Object title:', layout.title);

// For hypercube objects (charts, tables)
if (layout.qHyperCube) {
  const data = layout.qHyperCube.qDataPages[0].qMatrix;
  console.log('Data rows:', data.length);
  
  // Process the data
  data.forEach((row, index) => {
    const values = row.map(cell => cell.qText || cell.qNum);
    console.log(`Row ${index + 1}:`, values);
  });
}

// Make selections on the object
await object.selectValues(0, ['Value1', 'Value2']); // Select in first dimension
await object.clearSelections();

// Get object properties
const properties = await object.getProperties();
console.log('Object properties:', properties);

Creating Session Objects

Create temporary objects for custom data analysis

typescript
// Create a session object for data extraction
const sessionObject = await app.createSessionObject({
  qInfo: { qType: 'my-custom-object' },
  qHyperCubeDef: {
    qDimensions: [
      {
        qDef: {
          qFieldDefs: ['Product'],
          qFieldLabels: ['Product Name']
        }
      },
      {
        qDef: {
          qFieldDefs: ['Region']
        }
      }
    ],
    qMeasures: [
      {
        qDef: {
          qDef: 'Sum(Sales)',
          qLabel: 'Total Sales'
        }
      },
      {
        qDef: {
          qDef: 'Avg(Price)',
          qLabel: 'Average Price'
        }
      }
    ],
    qInitialDataFetch: [
      {
        qLeft: 0,
        qTop: 0,
        qWidth: 4,
        qHeight: 100
      }
    ]
  }
});

// Get the data
const layout = await sessionObject.getLayout();
const matrix = layout.qHyperCube.qDataPages[0].qMatrix;

// Process session object data
const processedData = matrix.map(row => ({
  product: row[0].qText,
  region: row[1].qText,
  totalSales: row[2].qNum,
  avgPrice: row[3].qNum
}));

console.log('Session object data:', processedData);

// Don't forget to destroy session objects when done
await sessionObject.destroy();

Data Export Examples

Export to JSON

typescript
async function exportAppData(app: QlikApp, objectId: string) {
  const object = await app.getObject(objectId);
  const layout = await object.getLayout();
  
  if (layout.qHyperCube) {
    const data = layout.qHyperCube.qDataPages[0].qMatrix;
    const headers = layout.qHyperCube.qDimensionInfo
      .map(dim => dim.qFallbackTitle)
      .concat(layout.qHyperCube.qMeasureInfo.map(measure => measure.qFallbackTitle));
    
    const exportData = {
      title: layout.title,
      headers,
      data: data.map(row => 
        row.map(cell => ({
          text: cell.qText,
          number: cell.qNum,
          state: cell.qState
        }))
      ),
      exportTime: new Date().toISOString()
    };
    
    // Save to file or send to API
    const json = JSON.stringify(exportData, null, 2);
    console.log('Exported data:', json);
    
    return exportData;
  }
}

// Usage
const exportedData = await exportAppData(app, 'sales-chart-id');

💡 Best Practices

Performance: Cache app instances when working with multiple operations
Error Handling: Always handle app access errors gracefully
Memory Management: Destroy session objects when no longer needed
Data Fetching: Use appropriate page sizes for large datasets
Selection State: Clear selections when switching between operations
Authentication: Check authentication status before app operations