Windows update breaks QlikView server 11.20 SR10

Update: Turns out it is the “Update for Windows Server 2012 (KB3013767)” that when installed on the server in question prevents the QlikView Directory Service to start. Installing the other two updates mentioned below (KB3004365 and KB3029449) does not affect QV operation.

 

While doing regular maintenance of a QlikView server (running 11.20 SR8) recently (as part of my daytime job), the latest Windows service packs were installed, as usual. This is normally just routine procedure, but not this time.

QlikView Directory Service fails to start
QlikView Directory Service fails to start

After installation was done and the server restarted, it was impossible to log into the QlikView Access Point (i.e. the system’s web UI). The reason was that QlikView’s Directory Service, QDS, failed to start. Even manual attempts at starting it gave the error shown to the right. The error dialog mentions dependencies that fail to start, but this particular service does not have any dependencies listed in its properties dialog. Strange…

Continue reading “Windows update breaks QlikView server 11.20 SR10”

Using CoffeeScript to create QlikView extensions

I am not a Javascript fan. To be honest, I find it rather abusive. There are probably lots of theoretically sound reasons for designing the Javascript (=JS) syntax the way it is – but that does not make it more readable or easy to learn.

I am however a QlikView (=QV) fan. Or rather: QV is a very powerful data visualisation, exploration and discovery tool, but the main drawbacks is its somewhat dated visualisation options. In a world used to fancy angular.js based dynamic web sites and great looking HighCharts graphs, QV’s visualisation options aren’t quite up there.

QV however has a rather interesting “extension” mechanism. You can create object extensions that add new visualisations to QV, using JS to develop the extensions. Document extensions are used to modify the deeper levels of QV applications – very useful and cool (someone created a document extensions using the accelerometers in iPhones to enable new ways to interacts with QV applications – pretty cool!) but not the focus of this post.

So, we want to create QlikView object extensions. JS is the mandated language. Ouch. We can however use CoffeeScript to remove the bad parts of JS, making the code base smaller and more easy to read and maintain. CoffeeScript is very cool, lots of testimonies to it’s greatness out there (DropBox is using CoffeeScript these days, and have shared some experiences).

Note: You need to install node.js before CoffeeScript. I’ve tried this on both Windows 8.1 and OS X – compiling CoffeeScript works without problems on both platforms.

Tuns out this works quite well. Brian Munz of QlikTech has created a couple of very nice templates to make it easier to create extensions, I’ve taken the liberty of converting one of them to CoffeeScript, to show how easy it is to convert JS to CoffeeScript (and make my own future extension development easier).

The CoffeeScript code can also be found in my repo at GitHub.

The Javascript version first:

[code language=”text”]

var template_path = Qva.Remote + "?public=only&name=Extensions/template_simple/";
function extension_Init()
{
// Use QlikView’s method of loading other files needed by an extension. These files should be added to your extension .zip file (.qar)
if (typeof jQuery == ‘undefined’) {
Qva.LoadScript(template_path + ‘jquery.js’, extension_Done);
}
else {
extension_Done();
}
}

function extension_Done(){
//Add extension
Qva.AddExtension(‘template_simple’, function(){
//Load a CSS style sheet
Qva.LoadCSS(template_path + "style.css");
var _this = this;
//add a unique name to the extension in order to prevent conflicts with other extensions.
//basically, take the object ID and add it to a DIV
var divName = _this.Layout.ObjectId.replace("\", "_");
if(_this.Element.children.length == 0) {//if this div doesn’t already exist, create a unique div with the divName
var ui = document.createElement("div");
ui.setAttribute("id", divName);
_this.Element.appendChild(ui);
} else {
//if it does exist, empty the div so we can fill it again
$("#" + divName).empty();
}

//create a variable to put the html into
var html = "";
//set a variable to the dataset to make things easier
var td = _this.Data;
//loop through the data set and add the values to the html variable
for(var rowIx = 0; rowIx < td.Rows.length; rowIx++) {
//set the current row to a variable
var row = td.Rows[rowIx];
//get the value of the first item in the dataset row
var val1 = row[0].text;
//get the value of the second item in the dataset row
var m = row[1].text;
//add those values to the html variable
html += "value 1: " + val1 + " expression value: " + m + "<br />";
}
//insert the html from the html variable into the extension.
$("#" + divName).html(html);
});
}

//Initiate extension
extension_Init();
[/code]

Now the CoffeeScript version. A lot more readable, at least to me:

[code language=”text”]
template_path = Qva.Remote + "?public=only&name=Extensions/template_simple_coffeescript/"

extension_Init = ->
# Use QlikView’s method of loading other files needed by an extension. These files should be added to your extension .zip file (.qar)
if typeof jQuery == ‘undefined’
Qva.LoadScript(template_path + ‘jquery.js’, extension_Done)
else
extension_Done()

extension_Done = ->
# Add extension
Qva.AddExtension(‘template_simple_coffeescript’, ->
_this = this

# add a unique name to the extension in order to prevent conflicts with other extensions.
# basically, take the object ID and add it to a DIV
divName = _this.Layout.ObjectId.replace("\", "_")
if _this.Element.children.length == 0
# if this div doesn’t already exist, create a unique div with the divName
ui = document.createElement("div")
ui.setAttribute("id", divName)
_this.Element.appendChild(ui)
else
# if it does exist, empty the div so we can fill it again
$("#" + divName).empty()

# create a variable to put the html into
html = ""

# set a variable to the dataset to make things easier
td = _this.Data

# loop through the data set and add the values to the html variable
for rowIx in [0..(td.Rows.length-1)]

# set the current row to a variable
row = td.Rows[rowIx]

# get the value of the first item in the dataset row
val1 = row[0].text

# get the value of the second item in the dataset row
m = row[1].text

# add those values to the html variable
html += "value 1: " + val1 + " expression value: " + m + "<br />"

# insert the html from the html variable into the extension.
$("#" + divName).html(html)
)

# Initiate extension
@extension_Init()
[/code]

Note that you need to include the –bare option when compiling the CoffeeScript code:

[code language=”bash”]

coffee –bare –compile Script.coffee

[/code]

This will give us the following Javascript file, which is functionally equivalent to the first JS file above:

[code language=”text”]
// Generated by CoffeeScript 1.6.3
var extension_Done, extension_Init, template_path;

template_path = Qva.Remote + "?public=only&name=Extensions/template_simple_coffeescript/";

extension_Init = function() {
if (typeof jQuery === ‘undefined’) {
return Qva.LoadScript(template_path + ‘jquery.js’, extension_Done);
} else {
return extension_Done();
}
};

extension_Done = function() {
return Qva.AddExtension(‘template_simple_coffeescript’, function() {
var divName, html, m, row, rowIx, td, ui, val1, _i, _ref, _this;
_this = this;
divName = _this.Layout.ObjectId.replace("\", "_");
if (_this.Element.children.length === 0) {
ui = document.createElement("div");
ui.setAttribute("id", divName);
_this.Element.appendChild(ui);
} else {
$("#" + divName).empty();
}

html = "";
td = _this.Data;
for (rowIx = _i = 0, _ref = td.Rows.length – 1; 0 <= _ref ? _i <= _ref : _i >= _ref; rowIx = 0 <= _ref ? ++_i : –_i) {
row = td.Rows[rowIx];
val1 = row[0].text;
m = row[1].text;
html += "value 1: " + val1 + " expression value: " + m + "<br />";
}
return $("#" + divName).html(html);
});
};

this.extension_Init();
[/code]