AddSense Chrome 1.2.1: active objects, dimensions, measures, link to Catwalk

A new version of my Chrome extension for Qlik Sense, Add Sense, is now available in Chrome Web Store. This is a pretty big version, actually that’s why it has number 1.2.1, because a bug sneaked into 1.2.0 which I had to fix.

New app level operations

You reach the new functions from the app popup box:

In fact, most of the buttons are new. From the left to the right they are used for:

  • showing the script
  • listing the tables
  • exploring the data model (in Catwalk)
  • listing variables
  • listing dimensions
  • listing measures
  • listing extensions used
  • listing active objects

Data model

A number of the new functions helps you with the data model. You can see what tables are defined in the app, and list dimensions and measures (and copy their definition into a program of your choice, like Excel or something). But perhaps the best new function is the link to Catwalk. Click on the compass icon, and it will open Catwalk with your current app:

If you don’t know what Catwalk is it’s time to get to know it knopw. It’s an open source tool from Qlik that helps you explore the data model of a Qlik Sense app. If it doesn’t work on your server, you might need to whitelist it. Check the documentation! Originally I planned to do some visualization of the data model, but I realized that I cannot make anything better than Catwalk, so why not reuse it.

List all active objects

The Add Sense extension uses Angular and some CSS selectors to find Qlik objects in your page, whether it’s the standard Qlik Sense client or a mashup. This only works for visualizations that are either Qlik Sense standard visualizations or extensions built with the traditional Angular-based method. But in a custom built web app using Qlik you might choose to visualize the data in some other way. Qlik Sense objects used this way have previously not been available in Add Sense, you could not check their properties, monitor recalculation times etc.

With the new function to list all active objects that has changed. While the little boxes showed on the page start from the HTML DOM and Angular scopes, this function uses enigmajs and lists all objects active in the enigmajs session. It might look something like this:

Example from the demo app ‘History of the fortune 500’

It still needs to find the enigmajs session, which might not work in all cases. If you want to use the extension for a case where it does not work, please let me know, you might be able to fix that with just a very small change.

Dimensions and measures

The extension can now also list dimensions and measures.

Dimensions

You can use the copy function in the dialog to copy the contants to the clipboard and then into application of your choice, like Excel etc.

Measures

And that’s it for the new functions. Please let me know if there is anything you are missing.

Qlik Sense Global object

Sometimes when you are working with the Qlik Sense APIs you need access to information that is not connected to the Qlik Sense document you are working with, but rather to the QIX Engine running.

You find the apis for this in the global object in the Capabilities APIs, or in the Global class in the Engine API. While the Capabilities APIs only include very few methods, the full list of calls in the Engine API is much longer.

Finding the Global object

While there is a method in the Capabilities API to get the global object, in most cases you should not use it. In fact if you are building an extension you never should. Instead you should use the global property on the app.

That is because the getGlobal() method will open a new web socket to the engine, while app.global property will use the web socket used for the app. There is not reason to open another web socket to the server when you already have one, and in an extension there always is one.

The only situation getGlobal() should be used is when you do not have an open web socket, like in a mashup before the app is opened. And in that case you might be better off with a REST call.

Qlik nebula.js – use in Qlik Sense

Previously I have written about Qliks new nebula.js framework: how to build a visualization and how you can use it in a web page. But what if you want to use it in the Qlik Sense built-in client?

Nebula.js is a new framework, built on an architecture that differs a lot from the old Qlik Sense client and has a new API. This means nebula.js-based visualization won’t work in Qlik Sense.

Add a Qlik Sense wrapper

So to run your visualization in Qlik Sense you need to wrap it in something that supports the Qlik Sense extension API. You also need to add the qext file. Luckily nebula.js can do that for you. Just type:

nebula sense

and nebulajs will wrap your visualization so it can be used as a Qlik Sense extension. You find the result in the [visualization]-ext directory, so for nova -table it will be nova-table-ext. Just copy the entire directory to your Extension directory (assuming you’re using Qlik Sense Desktop) and you will find your extension in the assets panel in sense:

and you can add your nebulaj.s visualization to your Qlik Sense app. You will also get a basic property panel, which works pretty well for the very basic nova-table.

Improving meta data

But the extension name is ‘nova-table’ and the icon used is the default extension icon and there is no description. You might be tempted to fix this in the generated qext file, but don’t do that! There is a better way. Start by getting some help by typing:

nebula sense -help

And you will get the following info:

This means we can add your meta info to a separate file and supply the filename as an argument to the ‘nebula sense’ command. So let’s create a file called meta.json and enter the following:

{
	"name": "Nebula table",
	"icon": "table",
	"description": "Nebula test table wrapped in a Qlik Sense extension"
}

Run the command:

nebula sense --meta meta.json

And copy the update -ext directory to youe Extension directory, overwriting the old version. You will see that the meta data has changed:

Working on the property panel

The wrapper also contains a default property panel, something you might want toimprove, for some visualizations you actually have to improve it to make the extension work. To do that we start with the default propertypanel. It’s in nova-table-ext/extDefinition.js, but it’s minified. To get it in a format that’s easier to work with we use the minify option to turn minification off (default is on):

nebula sense --minify false

And then copy the extDefinition.js file to the src directory. If you look at the file you can see a few things we could improve:

  • the settings section is commented out
  • features as export, exportData and snapshot are not supported

To make this work you also need to remove the define call the build script has wrapped around the definition (it will be added again when you build). So modify the file to:

const extDefinition = {
  definition: {
    type: 'items',
    component: 'accordion',
    items: {
      data: {
        uses: 'data',
      },
      settings: {
        uses: 'settings',
      },
    },
  },
  support: {
    export: true,
    exportData: true,
    snapshot: true,
    viewData: false,
  },
};

export default extDefinition;

And then run the build:

nebula sense --meta meta.json --ext src/extDefinition

Copy over the extension files again and you’ll se that you now have the ‘Appearance’ section (called ‘settings’ in the code) and export etc now works.

Using enigmajs in your Qlik Sense extension

Sometimes in your extension you need to acces the QIX Engine API. You might need to make or clear selections, apply a bookmark or something else. Traditionally you would use the Capabilities APIs for this. You would load the qlik module, get hold of the app with the help of the currApp() method, and call whatever function you needed.

But there is another way. You could do it the way the built-in client does, and use enigmajs instead. Enigmajs creates a javascript wrapper around the QIX api, a wrapper that includes all methods defined in the version of QIX your system is using. Qlik actually has open-sourced enigmajs, you can read more, and download it from the Github repository.

Enigmajs features

Important features of enigmajs:

  • it includes the complete QIX API for the actual version of QIX, while the capabilities API just includes a subset
  • it only includes the QIX Engine API, while the capabilities APIs wraps some client-side functionality too
  • methods calls return a Promise, that resolves when there is a response available
  • it handles the invalidation of objects as the selection state changes so it works well from inside an extension

Unlike the Capabilities APIs, enigmajs does not come with a lot of dependencies on requirejs, angularjs and Qlik Sense client code. This makes it well suited for use in envorinments where you use other frameworks, like react or future frameworks we have not heard of yet. Of course if you’re using it inside an extension, you already have all of these dependencies, so that is not so important.

Note that Qlik flags enigmajs as experimental in the current release. I would be very surprised if it goes away any time soon, but details in the implementation might change, you need to be aware of that.

Finding enigmajs in an extension

Qlik Sense creates a server side Generic Object for each instance of your extension (for all built-in charts too, actually). Around that Generic Object will be a javascript wrapper that exposes all the methods available. In the extension you can find it at:

this.backendApi.model.enigmaModel

It will expose all the methods defined in the Generic Object QIX engine API. As you can see, there are a lot of methods. It also has an app property, that exposes QIX Engine API app object. And the app has a global property, that is a wrapper around QIX Engine Global. This gives you access to the complete QIX Engine API.

An example

I have converted my Variable extension for Qlik Sense to use enigmajs instead of the Capabilities API, as versions before 4.0 did. The key call of the extension is after the conversion like this:

function setVariableValue(ext, name, value) {
        return ext.backendApi.model.enigmaModel.app.getVariableByName(name).then(function (v) {
            return v.setStringValue(value);
        });
    }
The parameter ext is a reference to the extension itself. Since methods return a Promise, I can use the then method to run an additional command after the first command resolves. The getVariableByName reurn an enigmajs wrapper aroud a QIX Engine Variable

Conclusion

If you need access to QIX Engine API from within your extension, enigmajs can help you with that. Unlike the Capabilities API it provides wrappers for all methods. But you should be aware that it only wraps engine api, not client-side functionality. It however works nicely within the client and invalidation and refresh of objects will work as expected.