Accessing system data and variables in a Qlik Sense extension

Sometimes when you are building a Qlik Sense extension you need to get access to system data. This is espescially true if you are trying to build something a bit more generic. Perhaps you need a list of fields, or dimensions, or measures. Or you need to work with variables.

If you are new to Qlik Sense development you might look in the API documentation for methods to get the data you need. Don’t do that!! Qlik Sense extension model is based on the idea that you use one Generic Object, described in the extensions initialProperties, and modified by the user in the property panel, and possibly programmatically (but that’s really advanced). So while using the API methods to get additonal data is the approach to use in mashups or Web apps that access Qlik data, you should avoid using them in a masup.

Why you shouldn’t

If you do use these api calls in your extension, you will get problems:

  • you might easily get a memory leak, or a ‘Generic Object leak’, where you create lots of Generic Objects
  • you can easily lose contral of all callback functions running when the generic objects are revalidated
  • if the user makes a snapshot, the API calls will access the latest version of the data, not the one in the snapshot and possibly give the wrong data
  • if the user tries to export your extension to PDF or Excel it might break, since the service responsible for those export does not have access to live data, only to the snapshot

If you absolutely must use these calls, you should at least turn export to PDF and Excel of and not allow snapshots of your extension.

What you should do instead

Luckily there are alternatives. These API calls all create Generic Objects, but since the Generic Object is a very flexible structure, you can actually configure the Generic Object behind your extension to provide the data you need. Here is a little table of what you could use:

You needDo not use API callInstead add to initialProperties
List of fieldsapp.getList("FieldList")qFieldListDef
List of measuresapp.getList("MeasureList")qMeasureListDef
List of dimensionsapp.getList("DimensionList")qDimensionListDef
List of variablesapp.getList("VariableList")qVariableListDef
Variable valueapp.variable.getContent(..)qStringExpression or
qValueExpression

You find a working example of this in my syslist extension just don’t use it, it’s meant as examples of how to get the data and doesn’t really do anything useful. But do grab the initialProperties part you need for your extension.

It looks like this:

When should you use these API calls

Well, no rule without an exception. While you should avoid using these calls in the API for the rendering part of your extension, you should use them in your property panel, if you for example need to provide a list of fields to the user. And in a mashup, they are definitely very useful. And the API has other calls, which you might want to use, but that vill mainly be when the user does something, like clicking a button etc.

Qlik Sense Generic Object I: General

Getting data out of a Qlik Sense app is based on a concept called Generic Object. Behind all charts, tables and listboxes in Qlik Sense lies a generic object. Also behind many of the other things you see in the Qlik Sense client lies generic objects:

  • the selection toolbar
  • the panel on the left side of the page, with lists of dimensions, measures and master objects
  • the sheet is a generic object

The purpose of the Generic Object is to make it easier to make client-side changes without having to change the QIX engine. Since the Generic Object is very flexible, many client side changes do not require any changes to the engine.  This is in contrast to how it works in QlikView, where all charts have different server-side implementations and client and server code are tightly coupled. This is also a reason why extensions are so powerful in Qlik Sense: to the QIX engine there is really no difference between built-in visualizations and extensions, they are all represented with a Generic Object.

Properties and layout

When you create a Generic Object you define its properties. This is a JSON structure, which you can define yourself. An example (from the peoplechart extension example):

There are two kind of properties:

  • user defined. Qlik only persists those and include them as-is in the layout, it is up to your code to use them for something
  • defined by Qlik Engine. These are validated by the Engine, and replaced in Engine output, the layout, by the calculated counterparts.

All properties defined by Engine start with a q, so it is good programming practice to let your own properties start with some other letter. The properties defined by Engine are documented here and the corresponding out data is documented here. Note that properties defined by the Qlik Sense client(like title etc) do NOT start with a q, the QIX engine does not really know what these are used for.

But the parameters known by the QIX Engine will determine the engines calculation. In the output from engine, called layout (though it’s not really the layout of a Generic Object) the definition of those properties will be replaced by the results. A hypercube definition (qHyperCubeDef) will be replaced by a actual hypercube (qHyperCube) containing the results from the calculation.

Generic Object context

Generic objects are everywhere in Qlik Sense. If you are building an extension, you define your Generic Object structure in the initialProperties property. If you are using the mashup API, you create generic objects with the createGenericObject method or one of the wrappers around it (createCube, createList, getList). In both these cases the Qlik Sense client framework will automatically refresh the Generic object with new data when it is invalidated (by for example new selections). If you are working directly on the protocol level, you need to fetch they new data yourself.