Enigma.create(config)
functionFunction 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)
functionFunction used to build a URL.
Parameters
urlConfig | This object describes the configuration that is sent into |
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
objectThis 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
interfaceThe 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()
eventHandles 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()
eventHandles 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()
eventHandles 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
interfaceThe 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
functionA function to use when instantiating the WebSocket, mandatory for Node.js.
new EnigmaError()
classError containing a custom error code.
Properties
code number | The error code as defined by |
enigmaError default=true boolean | No description |
Interceptor
interfaceInterceptor 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()
classImplement 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)
functionThis 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()
classImplement 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)
functionThis 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)
functionThis 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
interfaceThe 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
functionInit function that, if defined, will run when an API is instantiated. It runs with Promise and API object as parameters.
SenseConfiguration
ObjectThis 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()
classThe QIX Engine session object.
Sessionclosed()
eventHandles 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()
eventHandles 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()
eventHandles 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()
eventHandles 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)
eventHandles 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()
eventHandles 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?)
functionCloses 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()
functionEstablishes 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)
functionResumes 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)
functionFunction 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?)
functionSuspends 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');
});