Qlik Instance

Learn about the Qlik SDK instance, its lifecycle, and how to manage it effectively in your applications.

Instance Overview

The Qlik instance is the main entry point for interacting with Qlik environments. It manages authentication, connection state, and provides access to all Qlik APIs.

Key Responsibilities

• Authentication and session management
• Connection to Qlik environment
• API endpoint access
• Error handling and recovery

Instance State

Connected
Ready for operations
Connecting
Establishing connection
Disconnected
No active connection

Creating Instances

Basic Instance Creation

typescript
import Qlik from 'qlik';

// Create a new Qlik instance
const qlik = new Qlik({
  host: 'your-tenant.us.qlikcloud.com',
  webIntegrationId: 'your-web-integration-id'
});

// The instance is ready to use
console.log('Qlik instance created:', qlik);

Multiple Instances

You can create multiple instances for different environments or tenants

typescript
// Development environment
const qlikDev = new Qlik({
  host: 'dev-tenant.us.qlikcloud.com',
  webIntegrationId: process.env.DEV_WEB_INTEGRATION_ID
});

// Production environment  
const qlikProd = new Qlik({
  host: 'prod-tenant.us.qlikcloud.com',
  webIntegrationId: process.env.PROD_WEB_INTEGRATION_ID
});

// Use different instances for different purposes
const devApps = await qlikDev.getAppList();
const prodApps = await qlikProd.getAppList();

Instance Methods

Connection Management

Check Connection Status

typescript
// Check if instance is connected and authenticated
const isConnected = await qlik.isAuthenticated();

if (isConnected) {
  console.log('✅ Connected and ready');
  // Proceed with operations
} else {
  console.log('❌ Not connected, authentication required');
  await qlik.authenticateToQlik();
}

Manual Connection

typescript
// Explicit authentication
try {
  await qlik.authenticateToQlik();
  console.log('Authentication successful');
} catch (error) {
  console.error('Authentication failed:', error);
  // Handle authentication failure
}

Instance Information

typescript
// Get instance configuration
console.log('Host:', qlik.config.host);
console.log('Secure:', qlik.config.secure);
console.log('Port:', qlik.config.port);

// Get connection info (after authentication)
const connectionInfo = await qlik.getConnectionInfo();
console.log('User ID:', connectionInfo.userId);
console.log('Tenant ID:', connectionInfo.tenantId);

Instance Lifecycle

Lifecycle Management

typescript
class QlikService {
  private qlik: Qlik | null = null;

  async initialize(): Promise<void> {
    // Create instance
    this.qlik = new Qlik({
      host: process.env.QLIK_HOST!,
      webIntegrationId: process.env.QLIK_WEB_INTEGRATION_ID!
    });

    // Authenticate
    await this.qlik.authenticateToQlik();
    console.log('✅ Qlik service initialized');
  }

  async checkHealth(): Promise<boolean> {
    if (!this.qlik) return false;
    
    try {
      return await this.qlik.isAuthenticated();
    } catch (error) {
      console.error('Health check failed:', error);
      return false;
    }
  }

  async reconnect(): Promise<void> {
    if (!this.qlik) {
      throw new Error('Qlik instance not initialized');
    }

    try {
      await this.qlik.authenticateToQlik();
      console.log('✅ Reconnected successfully');
    } catch (error) {
      console.error('❌ Reconnection failed:', error);
      throw error;
    }
  }

  async cleanup(): Promise<void> {
    if (this.qlik) {
      await this.qlik.logout();
      this.qlik = null;
      console.log('✅ Qlik service cleaned up');
    }
  }

  getInstance(): Qlik {
    if (!this.qlik) {
      throw new Error('Qlik service not initialized');
    }
    return this.qlik;
  }
}

Best Practices

✅ Do's

• Reuse Qlik instances across your application
• Implement proper error handling for authentication
• Check connection status before making API calls
• Use singleton pattern for single-tenant applications
• Implement reconnection logic for long-running applications
• Clean up instances when no longer needed

❌ Don'ts

• Don't create new instances for every operation
• Don't ignore authentication failures
• Don't hardcode sensitive configuration values
• Don't assume the instance is always connected
• Don't forget to handle session expiration

Error Handling

Robust Error Handling

typescript
import Qlik, { QlikError, QlikAuthError } from 'qlik';

class RobustQlikService {
  private qlik: Qlik;
  private maxRetries = 3;

  constructor(config: QlikConfig) {
    this.qlik = new Qlik(config);
  }

  async withRetry<T>(operation: () => Promise<T>): Promise<T> {
    let lastError: Error;

    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      try {
        // Check authentication before operation
        if (!(await this.qlik.isAuthenticated())) {
          await this.qlik.authenticateToQlik();
        }

        return await operation();
      } catch (error) {
        lastError = error as Error;
        
        if (error instanceof QlikAuthError) {
          console.log(`Authentication error (attempt ${attempt}): ${error.message}`);
          // Try to re-authenticate
          await this.qlik.authenticateToQlik();
        } else if (error instanceof QlikError) {
          console.log(`Qlik error (attempt ${attempt}): ${error.message}`);
          if (attempt === this.maxRetries) break;
        } else {
          // Network or other errors
          console.log(`Unexpected error (attempt ${attempt}): ${error.message}`);
          if (attempt === this.maxRetries) break;
        }

        // Wait before retry
        await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
      }
    }

    throw new Error(`Operation failed after ${this.maxRetries} attempts: ${lastError.message}`);
  }

  async getApps() {
    return this.withRetry(() => this.qlik.getAppList());
  }
}