Guide to Qlik Sense ApplyPatches

patchwork

One of the more powerful calls in the QIX Api is the ApplyPatches call. It allows you to dynamically add, change or remove basically any property of a generic object. With it, you can allow users to dynamically change visualizations: reorder data, change dimensions and measures, add limitation etc etc. But using it in your implementation can be tricky.

Parameters

The ApplyPatches call only has two parameters (plus the handle, identifying which object we are patching:

NameDescriptionMandatoryType
qPatchesArray of patches.YesArray of NxPatch
qSoftPatchPatches are not savedNoBoolean

So it’s an arry and a boolean (true/false) flag. Let’s start with the flag. Setting the qSoftPatch flag to true does mean that the patched property is not saved, but it also has some other consequences:

  • you can change objects that you otherwise cannot, like published objects, or objects in apps you cannot change
  • the changes will only affect you, other users will not see them, they might very well apply a completely different patch to the same object
  • the changes will only affect the current session. If you disconnect and connect again, they will be lost and you will start over with the original version of the object

So if your goal is to allow users to dynamically change visualizations you would want qSoftPatch to be true. While the default value false works OK in Qlik Sense Desktop, it’s generally not something you would want to use in a server environment.

The array of patches

The array is a bit more difficult. It’s an array so you can change several properties with one call. For example if you change dimension or measure you should consider changing the title too, and probably do that in the same call.  Every entry(almost) in the array has three parameters:

NameDescriptionType
qOpOperation to perform. Add, remove or replace.String
qPathPath to the property.String
qValueThe value of the propertyString

The first parameter, qOp, is an easy one. In most cases you want to change a property, use ‘replace’. Occasionaly you want to add a property, use ‘add’. Rarely you want to remove a property, in that case use ‘remove’. 

The second parameter, qPath, is the path to the property, using / between the property names (not . as in javascript). Remember:

  • you’re patching properties, not the layout, so it’s /qHyperCubeDef/… not qHyperCube
  • for arrays you need to include the position in the array, and numbering starts with zero, so first dimension is /qHyperCubeDef/qDimensions/0/ etc
  • property structures can be complicated, speciallly the hypercube..
  • you can use my Chrome extension Add Sense to create the path argument. Show properties for the objects, switch to patch mode, copy the path

The second parameter, qPath, is the path to the property, using / between the property names (not . as in javascript). Remember:

  • you’re patching properties, not the layout, so it’s /qHyperCubeDef/… not qHyperCube
  • for arrays you need to include the position in the array, and numbering starts with zero, so first dimension is /qHyperCubeDef/qDimensions/0/ etc
  • property structures can be complicated, speciallly the hypercube..
  • you can use my Chrome extension Add Sense to create the path argument. Show properties for the objects, switch to patch mode

Some examples

A common case is when you want your users to be able to change the ordering of for example a table dynamically. Ordering of a hypercube is determined by the qInterColumnSortOrder property, an array with the column numbers in the order they should be used for sorting. If you want say the third column (which has number 2, since numbering starts with 0) you move the number 2 to the beginnging of the array and call applyPatches:

model.applyPatches( [{
  qPath: '/qHyperCubeDef/qInterColumnSortOrder',
  qOp: 'replace',
  qValue: JSON.stringify(sortorder)
}], true );

You can find a more complete example in the mashup I showed at Qonnections back in 2015.

Another example is when you want to reverse the ordering of a hypercube. You do this by toggling the boolean value of qReverseSort in the dimension or measure where you want to change the order. For the first dimension this will be:

model.applyPatches( [{
  qPath: '/qHyperCubeDef/qDimensions/0/qDef/qReverseSort',
  qOp: 'replace',
  qValue: JSON.stringify( !reversesort )
}], true );