Enigma.js

v2.7.3

JavaScript library for consuming Qlik backend services

Enigma.create(config)

function

Function used to create a QIX session.

Parameters

config

The enigma.js configuration object.

Returns

The QIX Engine session object.

Example minimal session creation

const enigma = require('enigma.js');
const schema = require('enigma.js/schemas/12.20.0.json');
const WebSocket = require('ws');
const config = {
  schema,
  url: 'ws://localhost:9076/app/engineData',
  createSocket: url => new WebSocket(url),
};
const session = enigma.create(config);

SenseUtilities.buildUrl(urlConfig)

function

Function used to build a URL.

Parameters

urlConfig

This object describes the configuration that is sent into buildUrl(config).

Returns

string

Returns the websocket URL.

Example of building and using a Qlik Sense-compatible WebSocket URL

const enigma = require('enigma.js');
const schema = require('enigma.js/schemas/12.20.0.json');
const SenseUtilities = require('enigma.js/sense-utilities');
const url = SenseUtilities.buildUrl({ host: 'my-sense-host', appId: 'some-app' });
const session = enigma.create({ schema, url });

errorCodes

object

This is a list of error codes that can be thrown from enigma.js API calls.

Properties

NOT_CONNECTED
default=-1
number

You're trying to send data on a socket that's not connected.

OBJECT_NOT_FOUND
default=-2
number

The object you're trying to fetch does not exist.

EXPECTED_ARRAY_OF_PATCHES
default=-3
number

Unexpected RPC response, expected array of patches.

PATCH_HAS_NO_PARENT
default=-4
number

Not an object that can be patched.

ENTRY_ALREADY_DEFINED
default=-5
number

This entry is already defined with another key.

NO_CONFIG_SUPPLIED
default=-6
number

You need to supply a configuration.

PROMISE_REQUIRED
default=-7
number

There's no promise object available (polyfill required?).

SCHEMA_STRUCT_TYPE_NOT_FOUND
default=-8
number

The schema struct type you requested does not exist.

SCHEMA_MIXIN_CANT_OVERRIDE_FUNCTION
default=-9
number

Can't override this function.

SCHEMA_MIXIN_EXTEND_NOT_ALLOWED
default=-10
number

Extend is not allowed for this mixin.

SESSION_SUSPENDED
default=-11
number

Session suspended - no interaction allowed.

SESSION_NOT_ATTACHED
default=-12
number

onlyIfAttached supplied, but you got SESSION_CREATED.

Handling an enigma.js error

const { NOT_CONNECTED } = require('enigma.js/error-codes');
try {
  const layout = await model.getLayout();
} catch (err) {
  if (err.code === NOT_CONNECTED) {
    console.log('Tried to communicate on a session that is closed');
  }
}

API

interface

The API for generated APIs depends on the QIX Engine schema you pass into your Configuration, and on what QIX struct the API has.

All API calls made using the generated APIs will return promises that are either resolved or rejected depending on how the QIX Engine responds.

Properties

id
string

Contains the unique identifier for this API.

type
string

Contains the schema class name for this API.

genericType
string

Corresponds to the qInfo.qType property on the generic object's properties object.

session

The QIX Engine session object.

handle
number

Contains the handle QIX Engine assigned to the API. Used interally in enigma.js for caches and JSON-RPC requests.

Example using `global` and `generic object` struct APIs

global.openDoc('my-document.qvf').then((doc) => {
  doc.createObject({ qInfo: { qType: 'my-object' } }).then(api => { });
  doc.getObject('object-id').then(api => { });
  doc.getBookmark('bookmark-id').then(api => { });
});

APIchanged()

event

Handles changes on the API. The changed event is triggered whenever enigma.js or QIX Engine has identified potential changes on the underlying properties or hypercubes and you should re-fetch your data.

Bind the `changed` event

api.on('changed', () => {
  api.getLayout().then(layout => { });
});

APIclosed()

event

Handles closed API. The closed event is triggered whenever QIX Engine considers an API closed. It usually means that it no longer exists in the QIX Engine document or session.

Bind the `closed` event

api.on('closed', () => {
  console.log(api.id, 'was closed');
});

APItraffic()

event

Handles JSON-RPC requests/responses for this API. Generally used in debugging purposes. traffic:* will handle all websocket messages, traffic:sent will handle outgoing messages and traffic:received will handle incoming messages.

Bind the traffic events

// bind both in- and outbound traffic to console.log:
api.on('traffic:*', console.log);
// bind outbound traffic to console.log:
api.on('traffic:sent', console.log);
// bind inbound traffic to console.log:
api.on('traffic:received', console.log);

Configuration

interface

The enigma.js configuration object.

Properties

schema
Object

Object containing the specification for the API to generate. Corresponds to a specific version of the QIX Engine API.

url
string

String containing a proper websocket URL to QIX Engine.

Promise
Object

ES6-compatible Promise library.

suspendOnClose
default=false
boolean

Set to true if the session should be suspended instead of closed when the websocket is closed.

mixins
default=[]

Mixins to extend/augment the QIX Engine API. Mixins are applied in the array order.

requestInterceptors
default=[]
Array

Interceptors for augmenting requests before they are sent to QIX Engine. Interceptors are applied in the array order.

responseInterceptors
default=[]
Array

Interceptors for augmenting responses before they are passed into mixins and end-users. Interceptors are applied in the array order.

protocol
default={}

An object containing additional JSON-RPC request parameters.

Example defining a configuration object

const enigma = require('enigma.js');
const WebSocket = require('ws');
const bluebird = require('bluebird');
const schema = require('enigma.js/schemas/12.20.0.json');

const config = {
 schema,
 url: 'ws://localhost:4848/app/engineData',
 createSocket: url => new WebSocket(url),
 Promise: bluebird,
 suspendOnClose: true,
 mixins: [{ types: ['Global'], init: () => console.log('Mixin ran') }],
 protocol: { delta: false },
};

enigma.create(config).open().then((global) => {
  // global === QIX global interface
  process.exit(0);
});

ConfigurationcreateSocket

function

A function to use when instantiating the WebSocket, mandatory for Node.js.

new EnigmaError()

class
extendsError

Error containing a custom error code.

Properties

code
number

The error code as defined by errorCodes.

enigmaError
default=true
boolean

No description

Interceptor

interface

Interceptor is a concept similar to mixins, but runs on a lower level. The interceptor concept can augment either the requests (i.e. before sent to QIX Engine), or the responses (i.e. after QIX Engine has sent a response). The interceptor promises run in parallel to the regular promises used in enigma.js, which means that it can be really useful when you want to normalize behaviors in your application.

new InterceptorRequest()

class
implementsInterceptor

Implement a request interceptor

const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

const session = enigma.create({
  schema,
  url: 'ws://localhost:9076/app/engineData',
  createSocket: (url) => new WebSocket(url),
  requestInterceptors: [{
    onFulfilled: function logRequest(sessionReference, request) {
      console.log('Request being sent', request);
      return request;
    }
  },
});

InterceptorRequestonFulfilled(session, request)

function

This method is invoked when a request is about to be sent to QIX Engine.

Parameters

session

The QIX Engine session object.

request
Object

The JSON-RPC request that will be sent.

new InterceptorResponse()

class
implementsInterceptor

Implement a request interceptor

const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

const session = enigma.create({
  schema,
  url: 'ws://localhost:9076/app/engineData',
  createSocket: (url) => new WebSocket(url),
  responseInterceptors: [{
    onRejected: function logError(sessionReference, request, error) {
      console.log('Error returned from QIX engine', error, 'Originating request:', request);
      // throw error so it's continued to be rejected:
      throw error;
    }
  },
});

InterceptorResponseonFulfilled(session, request, result)

function

This method is invoked when a promise has been successfully resolved; use this to modify the result or reject the promise chain before it is sent to mixins.

Parameters

session

The QIX Engine session object.

request
Object

The JSON-RPC request resulting in this response.

result
Object

Whatever the previous interceptor is resolved with.

InterceptorResponseonRejected(session, request, error)

function

This method is invoked when a previous interceptor has rejected the promise; use this to handle, for example, errors before they are sent into mixins.

Parameters

session

The QIX Engine session object.

request
Object

The JSON-RPC request resulting in this error.

error
Object

Whatever the previous interceptor is rejected with.

Mixin

interface

The mixin concept allows you to add or override QIX Engine API functionality. A mixin is basically a JavaScript object describing which types it modifies, and a list of functions for extending and overriding the API for those types.

QIX Engine types like, for example, GenericObject, Doc, GenericBookmark, are supported but also custom GenericObject types such as barchart, story and myCustomType. An API will get both their generic type as well as custom type mixins applied.

Mixins that are bound to several different types can find the current API type in the genericType or type members. this.type would, for instance, return GenericObject and this.genericType would return barchart.

See the Mixins examples on how to use it. Below is an outline of what the mixin API consists of.

Properties

types
string | Array<string>

String or array of strings containing the API-types that will be mixed in.

extend
Object

Object literal containing the methods that will be extended on the specified API.

override
Object

Object literal containing the methods to override existing methods.

Mixininit

function

Init function that, if defined, will run when an API is instantiated. It runs with Promise and API object as parameters.

SenseConfiguration

Object

This object describes the configuration that is sent into buildUrl(config).

Properties

appId
string

The app ID. If omitted, only the global object is returned. Otherwise both global and app object are returned.

noData
default=false
boolean

Whether to open the app without data.

secure
default=true
boolean

Set to false if an unsecure WebSocket should be used.

host
string

Host address.

port
number

Port to connect to.

prefix
default='"/"'
string

The absolute base path to use when connecting. Used for proxy prefixes.

subpath
default='""'
string

The subpath.

route
default='""'
string

Used to instruct Proxy to route to the correct receiver.

identity
default='""'
string

Identity to use.

urlParams
default={}
Object

Used to add parameters to the WebSocket URL.

ttl
number

A value in seconds that QIX Engine should keep the session alive after socket disconnect (only works if QIX Engine supports it).

new Session()

class

The QIX Engine session object.

Sessionclosed()

event

Handles closed state. This event is triggered when the underlying websocket is closed and config.suspendOnClose is false.

Handling session closed

session.on('closed', () => {
  console.log('Session was closed, clean up!');
});

Sessionnotification()

event

Handles all JSON-RPC notification events, 'notification:* or handles a specific JSON-RPC notification event, 'notification:OnConnected'. These events depend on the product from which you use QIX Engine.

Bind the notification events

// bind all notifications to console.log:
session.on('notification:*', console.log);
// bind a specific notification to console.log:
session.on('notification:OnConnected', console.log);

Sessionopened()

event

Handles opened state. This event is triggered whenever the websocket is connected and ready for communication.

Bind the session opened event

session.on('opened', () => {
  console.log('Session was opened');
});

Sessionresumed()

event

Handles resumed state. This event is triggered when the session was properly resumed. It is useful in scenarios where, for example, you can close blocking modal dialogs and allow the user to interact with your application again.

Handling session resumed

session.on('resumed', () => {
  console.log('Session was resumed, we can close that "reconnecting" dialog now');
});

Sessionsuspended(evt)

event

Handles suspended state. This event is triggered in two cases (listed below). It is useful in scenarios where, for example, you want to block interaction with your application until you resume again. Or, if config.suspendOnClose is true and there was a network disconnect (socket closed) or if you ran session.suspend().

Parameters

evt

Event object.

Handling session suspended

session.on('suspended', () => {
  console.log('Session was suspended, retrying...');
  session.resume();
});

Sessiontraffic()

event

Handles websocket messages. Generally used for debugging purposes. traffic:* will handle all websocket messages, traffic:sent will handle outgoing messages, and traffic:received will handle incoming messages.

Bind the traffic events

// bind both in- and outbound traffic to console.log:
session.on('traffic:*', console.log);
// bind outbound traffic to console.log:
session.on('traffic:sent', console.log);
// bind inbound traffic to console.log:
session.on('traffic:received', console.log);

Sessionclose(code?, reason?)

function
emitsclosed

Closes the websocket and cleans up internal caches. Also triggers the closed event on all generated APIs. Note that you have to manually invoke this when you want to close a session and config.suspendOnClose is true.

Parameters

code
default=1000
number

The reason code for closing the connection.

reason
default='""'
string

The human readable string describing why the connection is closed.

Returns

Promise<Object>

Eventually resolved when the websocket has been closed.

Closing a session

session.close().then(() => {
  console.log('Session was closed');
});

Sessionopen()

function
emitsopened

Establishes the websocket against the configured URL and returns the Global instance.

Returns

Promise<Object>

Eventually resolved if the connection was successful.

Opening a sesssion

session.open().then(() => {
  console.log('Session was opened');
});

Sessionresume(onlyIfAttached)

function
emitsresumed

Resumes a previously suspended enigma.js session by recreating the websocket and, if possible, reopen the document as well as refreshing the internal cashes. If successful, changed events will be triggered on all generated APIs, and on the ones it was unable to restore, the closed event will be triggered.

Parameters

onlyIfAttached
boolean

If true, resume only if the session was reattached properly.

Returns

Promise<Object>

Eventually resolved when the websocket (and potentially the previously opened document, and generated APIs) has been restored; it is rejected when it fails any of those steps, or when onlyIfAttached is true and a new session was created.

Resuming a session

session.resume(true).then(() => {
  console.log('Session was resumed by re-attaching');
});

Sessionsend(request)

function

Function used to send data on the RPC socket.

Parameters

request
Object

The request to be sent. (data and some meta info)

Returns

Object

Returns a promise instance.

Sessionsuspend(code?, reason?)

function

Suspends the enigma.js session by closing the websocket and rejecting all method calls until it is has resumed again.

Parameters

code
default=4000
number

The reason code for suspending the connection.

reason
default='""'
string

The human readable string describing why the connection is suspended.

Returns

Promise<Object>

Eventually resolved when the websocket has been closed.

Suspending a session

session.suspend().then(() => {
  console.log('Session was suspended');
});
Was this page helpful?