dataquarium

How to Calculate a Value from the Qlik Engine

March 2, 2020

This post is a preview of concepts taught at the Masters Summit for Qlik APIs. Want to learn more about these topics? Join us this Fall in New Orleans or Madrid for 3 days of hands-on Qlik API training.

A common usecase in Qlik extensions, mashups, and web apps is displaying the calculation of a single formula. This usecase shows up frequently in the form of 1 or more KPIs to be displayed across a page. So how do you get the Engine to calculate a formula and return the results? As it turns out, there are a whopping FIVE different ways to calculate a value. Let’s break down the methods and their differences.

For each method, we will use an example Qlik formula of money(sum(Sales)). This formula will sum up the numeric values of a [Sales] field. It will also apply currency formatting to the string representation of the number. The result in Qlik will be a Dual value with values:

NumberString
1250$1,250

All code examples below assume that enigma.js has been used to open an app under the doc variable.;


Method 1: Doc.Evaluate

The Qlik Doc class, which represents an open Qlik app, has an Evaluate method. Evaluate allows us to calculate any formula and return the result as a string:

const value = doc.then(d => d.evaluate("money(sum(Sales))"));
value.then(console.log); // logs the string "$1,250"

This method works well when you just need to quickly display a value, with no other modifications or updates.

Update Frequency: Only when you call it directly

Return Format: string

Use When: You just want to display a value as formatted in Qlik, with no need to worry about seeing an updated value.


Method 2: Doc.EvaluateEx

The previous method of Evaluate only returns the string representation of the calculation. This is not useful if we want to work with the number in other ways in our app. For example, we might want to include the number in our own calculations or apply our own formatting to it. In that case, we can use EvaluateEx instead, which will give us both the string and numeric values of the calculation.

const value = doc.then(d => d.evaluateEx("money(sum(Sales))"));
value.then(console.log);
/* Logs:
  {
    qText: "$1,250",
    qIsNumeric: true,
    qNumber: 1250
  }
*/

This additional data allows us to work with the numeric value of the calculation, if it has one.

Update Frequency: Only when you call it directly

Return Format: string and number

Use When: You just want to work with a numeric value from Qlik, without worrying about updates if selections happen


Method 3: A Generic Object with a qStringExpression

While our Evaluate methods are easy to use, their pitfall is that they don’t notify us if our value should change because of selections. If we want our value to always reflect the latest selection state, we should use a generic object instead. Generic objects can use the qStringExpression property to keep track of the string result of a formula across selection changes:

const obj = doc.then(d => d.createSessionObject({
  qInfo: {
    qType: "my-kpi"   
  },
  value: {
    qStringExpression: {
      qExpr: "money(sum(Sales))"
    }
  }
}))

The calculated string value for our formula will be available on the layout of the generic object. To get the latest value of our expression whenever it changes, we can listen for object changes and ask for the latest layout:

obj.then(model => {
  model.on("changed", () => {
    model.getLayout().then(layout => { 
      console.log(layout.value) 
    });
  });
});

Another benefit of using generic objects is that we can put more than 1 string expression on the object. We could have 1 generic object that is responsible for a list of expressions, like:

const obj = doc.then(d => d.createSessionObject({
  qInfo: {
    qType: "my-kpi"   
  },
  firstKpi: {
    qStringExpression: {
      qExpr: "money(sum(Sales))"
    }
  },
  secondKpi: {
    qStringExpression: {
      qExpr: "money(avg(Margin))"
    }
  }
  // etc...
}));

Update Frequency: Updates with selections

Return Format: string

Use When: You want to display a value as formatted in Qlik and want that value updated with selection changes


Method 4: A Generic Object with a qValueExpression

Just like we had evaluate to get string values and evaluateEx to get string and numeric values, qStringExpression has a related type called qValueExpression which will give us back both the string and numeric value of a formula. The code looks similar to the qStringExpression example above:

const obj = doc.then(d => d.createSessionObject({
  qInfo: {
    qType: "my-kpi"   
  },
  value: {
    qValueExpression: {
      qExpr: "money(sum(Sales))"
    }
  }
}));

obj.then(model => {
  model.on("changed", () => {
    model.getLayout().then(layout => { 
      console.log(layout.value) 
    });
  });
});

Update Frequency: Updates with selections

Return Format: string and number

Use When: You want to get a numeric value from Qlik, updated with selection changes


Method 5: A HyperCube with 1+ Measures, No Dimensions

While the previous 4 methods are common for calculating formulas, Nick Webster has experimented with using HyperCubes to manage lists of KPIs in large applications. The Qlik Sense client also uses HyperCubes for KPI objects. During Nick’s “Solution Architecture & Performance” session at Masters Summit, he’ll discuss this approach and its benefits which include performance and integration with the master library.


Register soon to get early bird pricing on the Masters Summit for Qlik APIs, a 3 day training event happening this Fall in New Orleans and Madrid.

qlik