Skip to main content
Announcements
July 15, NEW Customer Portal: Initial launch will improve how you submit Support Cases. IMPORTANT DETAILS
Yianni_Ververis
Employee
Employee

Qlik Sense is getting better and better on every release!


I was working on a large website using Qlik Sense 2.1 and the Capability APIs where I used the template that I had created and blogged about Creating a website with Angular and the Capabilities API‌‌. I had almost finished the project, when we decided to upgrade to 2.2. Everything was fine, I was cleaning up my code and I was ready to deliver the project when we realized that most of the charts, had no interactivity!

So, lets fix our template to work properly in 2.2.

One of the two issues was the css. In 2.1 we had to use qlikui.css and client.css. In 2.2 these were replaced by qlik-styles.css. So in index.html replace L17-L18

<link rel="stylesheet" href="http://localhost:4848/resources/autogenerated/qlikui.css">

<link rel="stylesheet" href="http://localhost:4848/resources/assets/client/client.css" media="all">

with

<link rel="stylesheet" href="http://localhost:4848/resources/autogenerated/qlik-styles.css">

Also, remove the icon fix we had in index.less and remove L134-L136. This has been fixed in the new stylesheet.

.sel-toolbar-span-icon {

    top: -10px;

}

Another issue we found is that, we have to make sure that overflow-y: auto; is in both the html and body. We had that from beginning in this template but it seems to break things in 2.2 if it is only on body and not the html.

In the js/lib/main.js I used in the grid-service in order to make angular work. This has also been fixed and you can remove L30

define( "client.services/grid-service", {} );

Now, going to my last and more important issue, on why the interactivity was broken in 2.2. I started the blog by stating that "Qlik Sense is getting better and better on every release!" and this is so true. I spend several days trying to figure out why the interactivity was broken when I was moving from pages to pages and on random times. The issue was that simply the engine got so much faster on delivering the objects, that Angular could not keep up with it! Really, when the Capability App API app.getObject() is looking for the id to replace the html with, is looking for the parent element width and height. In my case, all of the objects, most of the time, had the canvas drawn with 0 height and width due to that! So, in order to fix this, unfortunately, I had to add a 1/2 second delay on getting my objects. So in the js/services/api.js, wrap L18-L24 in a timeout function

  setTimeout(function(){

     angular.forEach(obj, function(value, key) {

        app.obj.app.getObject(value, value).then(function(model){

           app.obj.model.push(model);

           deferred.resolve(value);

        });

        promises.push(deferred.promise);

     });

  }, 500);

I would add this only if you have the interactivity issues like I have described above. In cases that you have small projects like this one and you do not have a lot of dependencies, this may not be needed at all!

Updated Git: GitHub - yianni-ververis/capabilities-api-angular-template: A simple mvc template for building webpa...

Capability APIs documentation: https://help.qlik.com/en-US/sense-developer/2.2/Subsystems/APIs/Content/mashup-api-reference.htm

Happy coding!!

Yianni

9 Comments
clarelam
Contributor II
Contributor II

Hi Yianni,

I'm trying to setup your template locally with QS2.2, however I can't seem to get it to display the data from the Helpdesk Management app. All I see on http://localhost:4848/extensions/angularTemplate/index.html are the tabs Dashboard and Performance, and the link to Qlik in the footer. I downloaded the latest code from github and followed the steps in the original blog post and also this one.

Do you have any suggestions?

Thanks,

Clare

0 Likes
1,061 Views
Yianni_Ververis
Employee
Employee

Hello Clare,

First you need to go through the first tutorial on how to set it up, which I assume is the one you mention as the "original psot".

Creating a website with Angular and the Capabilities API

Then you need to check all of the following paths:

  • index.html

  <link rel="stylesheet" href="js/vendor/bootstrap/dist/css/bootstrap.min.css">

  <link rel="stylesheet" href="http://localhost:4848/resources/autogenerated/qlik-styles.css">

  <script src="http://localhost:4848/resources/assets/external/requirejs/require.js" data-main="js/lib/main.js"></script>

  • js/lib/main.js

var scriptsUrl = 'http://localhost:4848/extensions/angularTemplate/';

baseUrl: "http://localhost:4848/resources",

  • js/lib/app.js, make sure all of the variables are correct.
  • The files should be under 

C:\Users\<your username in win7/win10>\Documents\Qlik\Sense\Extensions\angularTemplate

  • You need to make sure the Desktop Sense is running, otherwise you do not have a localhost:4848

If you did all of that and you still do not see anything, please send me a screenshot of the console

Thank you for trying it out,

Yianni

0 Likes
1,061 Views
clarelam
Contributor II
Contributor II

Amazing, thanks Yianni! I was missing "data-main="js/lib/main.js" from the script line in index.html. Pretty crucial!

Thanks,

Clare

0 Likes
1,061 Views
Yianni_Ververis
Employee
Employee

Yes it is!!

I am glad it worked for you. I am using this template in all of my apps that I build in the Qlik Demo Team.

Best,

Yianni

0 Likes
1,061 Views
clarelam
Contributor II
Contributor II

The template works really well, and the directives are really useful

I'm still quite new to using Angular, so I have another question - how do I add another dependency for one of the views? I've added to the path to require.config and I then tried to add it to "angular.module('myApp', [ 'ngAnimate', 'ui.router', 'ui.bootstrap', 'three']" but I'm getting an error saying that the module is not available:

require.js:43 Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:

Error: [$injector:modulerr] Failed to instantiate module three due to:

Error: [$injector:nomod] Module 'three' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

Thanks for your help!

Clare

0 Likes
1,061 Views
Yianni_Ververis
Employee
Employee

Hello Clare and I am glad you found the template useful.

By dependancy you most likely mean another page so here are the steps:

  1. Copy performance controller and rename it to 'newpage' under js/controllers/newpage.js
  2. Change L12 to
    .controller('controller.newpage', function ($scope, $rootScope, $location, $injector, api, utility) {
  3. Copy the peformance html and rename it as newpage.html under views/
  4. Add it to your require config L13 under js/lib/main.js
    'controller.newpage': scriptsUrl + 'js/controllers/newpage',
  5. And then load it at L70
    'controller.newpage',

I believe that's it! Try it and let me know if it works for you

Best,

Yianni

0 Likes
1,061 Views
clarelam
Contributor II
Contributor II

Hi Yianni,

I'm trying to add the threejs library to render a globe in one of my views. I have the minified JS file in js/vendors/globe/three.min.js and in my view controller I have lines like:

var loader = new THREE.TextureLoader();

What do I need to do to be able to use the THREE in:

app.obj.angularApp

    .controller('controller.globe', function ($scope, $rootScope, $location, $injector, api, utility, THREE) { ...

Thanks,

Clare

0 Likes
890 Views
Yianni_Ververis
Employee
Employee

Hello Clare,

I usually use the d3 library.

  1. Add it to your require config L13 under js/lib/main.js
    'THREE': scriptsUrl + 'js/vendors/globe/three.min',
  2. Then load it at L70
    'THREE'

app.obj.angularApp

    .controller('controller.globe', function ($scope, $rootScope, $location, $injector, api, utility, THREE) { ...

and then call var loader = new THREE.TextureLoader();

Try this and let me know.

Best,

Yianni

0 Likes
890 Views
clarelam
Contributor II
Contributor II

Hi Yianni,

I've tried as you suggested but I'm getting the error:

require.js:44 Error: [$injector:unpr] Unknown provider: THREEProvider <- THREE

At your step 2, do you mean add 'THREE' into the require function or to "angular.bootstrap( document, ["myApp", "qlik-angular"] );"?

Do you have an example where you load in the d3?

Thanks for your help,

Clare

0 Likes
890 Views