Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
mguthrie
Contributor II
Contributor II

Qlik sense API question

I am trying to write a visual extension for as a test for an app I want to build here for work. I normally work with C# so most of the angular stuff is still really new to me. I am trying to retrieve a listing of the current pages in the current working app. I can call the app.getList() function with the 'sheet' parameter and it seems to work fine. However when I try to bind to the scope object it seems like it is never populated with anything. This is the current initial code I am using. When I check the console sheetlist is populated with all of the sheets in the app but when i bind the sheets variable in the template it doesn't do anything. Any help from you guys would be most appreciated. Am I doing this completely wrong?

define( [

'jquery',

'./properties',

'text!./template.ng.html',

'qlik'

],

function ( $, props, ngTemplate, qlik ) {

'use strict';

return {

definition: props,

initialProperties: {},

snapshot: {canTakeSnapshot:true},

template: ngTemplate,

controller: ['$scope', function($scope){

$scope.myTitle = "This is my angularJS menu";

var app = qlik.currApp();

$scope.sheets = app.getList('sheet', function(reply){

var sheetList = [];

$.each(reply.qAppObjectList.qItems, function (key, value) {

sheetList.push({sheetId: value.qInfo.qId, sheetName: value.qData.title});

});

console.log('sheetlist', sheetList);

return sheetList;

});

}]

};

} );

Here is what i am using to test for the template.

<div qv-extension>

<b ng-bind="myTitle"/>

<pre ng-repeat="(key, val) in this">{{key}} = {{val|json}}</pre>

<b ng-repeat="sheet in sheets"><br />{{sheet}}</b>

</div>

1 Solution

Accepted Solutions
ErikWetterberg

Hi Mark,

Don't use getList in your extension, at least avoid it in rendering. It's better to add the data you need to the underlying generic object by adding the sheet list to initialProperties, something like this:

initialProperties: {

  qAppObjectListDef: {

     qType: 'sheet'

  }

}

You will then find the list of sheet in the layout. You don't have to handle the asynchronity, the client framework will do that for you and your extension might be snapshottable. You might need to include a qData property too, to get the fields you want.

You fin documentation for qAppListObjectDef here

More on generic objects:Introduction to Generic Object

Hope this helps

Erik Wetterberg

View solution in original post

6 Replies
_jespers_
Partner - Creator II
Partner - Creator II

Hi Mark,

You don't use return in your controller to pass variables to the template, you just assign them to the $scope variable. For example if you want to use a variable in the template called sheetlist, you assign the variable in the controller as $scope.sheetlist.

I did a few changes to your code and made it work.

define( [

        'jquery',

        './properties',

        'text!./template.html',

        'qlik'

    ],

    function ( $, props, ngTemplate, qlik ) {

        'use strict';

        return {

            definition: props,

            initialProperties: {},

            support: {

                snapshot: false,

                export: false,

                exportData: false

            },

            template: ngTemplate,

            paint: function ($element, layout) {

                return qlik.Promise.resolve();

            },

            controller: ['$scope', function($scope){

                $scope.myTitle = "This is my angularJS menu";

                var app = qlik.currApp();

                app.getList('sheet', function(reply){

                    $scope.sheetList = [];

                    $.each(reply.qAppObjectList.qItems, function (key, value) {

                        $scope.sheetList.push({sheetId: value.qInfo.qId, sheetName: value.qData.title});

                    });

                });

            }]

        };

    });

<div qv-extension style="height: 100%; position: relative; overflow: auto;" class="ng-scope">

    <b ng-bind="myTitle"/>

    <pre ng-repeat="(key, val) in this">{{key}} = {{val|json}}</pre>

    <b ng-repeat="sheet in sheetList"><br />{{sheet.sheetName}}</b>

</div>

Just make sure when you test this if you just paste this code in your original extension, remove your extension object from the sheet, reload and then add it back again.

ErikWetterberg

Hi Mark,

Don't use getList in your extension, at least avoid it in rendering. It's better to add the data you need to the underlying generic object by adding the sheet list to initialProperties, something like this:

initialProperties: {

  qAppObjectListDef: {

     qType: 'sheet'

  }

}

You will then find the list of sheet in the layout. You don't have to handle the asynchronity, the client framework will do that for you and your extension might be snapshottable. You might need to include a qData property too, to get the fields you want.

You fin documentation for qAppListObjectDef here

More on generic objects:Introduction to Generic Object

Hope this helps

Erik Wetterberg

_jespers_
Partner - Creator II
Partner - Creator II

Erik's answer is a much better solution.

As Erik wrote you will find the sheets in the layout, but since you said that you are pretty new to extensions, this might not be completely clear where this is. So I will just point out where you will find the sheets to make it a bit easier.

If you are in the controller you will find them in $scope.layout.qAppObjectList.qItems.

Regards

mguthrie
Contributor II
Contributor II
Author

Erik I seem to be having an issue with this. If i don't add a qData I dont actually see anything returned in my layout object. When I add qdata to the definition the extension doesn't seem to want to compile and the extension stops working in my test app. this was how I was setting it up in my initial properties file.

// JavaScript

define( [], function () {

    'use strict';

    return {

   qAppObjectListDef: { 

   qType: 'sheet',

   qData: {}

  }

    };

} );

I also tried adding in stuff in the qData portion such as qData: {id : qInfo.qId} which is how I think its supposed to be declared from the documents you linked but the same issue is occurring.

ErikWetterberg

Hi Mark,

If you have got a qAppObjectListDef in your properties you should always get a qAppObjectList in your layout, and since you will always have at least one sheet in you app it should have at least one entry.

But for the initialProperties changes to have effect you need to recreate (or convert) your extension object. So create a new one and see what happens.

The list you get will always contain the sheet id (under qInfo.qId) but might not contain the sheet title. If not you would use qData to get it, like this:

qData:{

  title:'/title'

}

Meaning that you want a property called title and in it you should have the value stored at the path '/title'.

Hope this helps

Erik Wetterberg

mguthrie
Contributor II
Contributor II
Author

Thank you. I think I neglected to readd the extension but the extra clarification on the qData element really helped as well. Thank you for your help.