35 Replies Latest reply: Aug 17, 2015 10:47 AM by Bryan Sng RSS

    Qlik sense extension load data without dimension

    Bryan Sng

      Hello guys,

       

      Is there any way I can access data from the app data model without using dimensions?

       

      I understand I can access data via layout.qHyperCube.qDataPages[0] if I add the necessary dimensions in.

       

      I also tried initialproperties such as the following but could not find it anywhere in the layout variable.

       

      define([], function () {

        return {

          version: 1.0,

          qHyperCubeDef: {

            qDimensions: ['mytestproperty1', 'mytestproperty2'],

            qMeasures: [],

            qInterColumnSortOrder: [],

            qInitialDataFetch: [{

              qWidth: 3,

              qHeight: 400

            }]

          }

        };

      });

       

      Do you guys have any advice? Thanks!

        • Re: Qlik sense extension load data without dimension
          Øystein Kolsrud

          There is a method called "GetTableData" for apps that might be what you are looking for. It allows you to access data directly from the loaded tables without going through hypercubes or list objects. You can find more information here:

           

          http://help.qlik.com/sense/en-us/developer/#../Subsystems/EngineAPI/Content/Classes/AppClass/AppClassGetTableDataMethod.…

          • Re: Qlik sense extension load data without dimension
            Alexander Karlsson

            Take a look at https://help.qlik.com/sense/en-us/developer/index.html#../Subsystems/Workbench/Content/CodeExamples/horizlist-extension-… which shows you how to use a listobject def instead of a hypercube.

             

            Also in your snippet you can't just pass in a string. You would pass in a NxDimension struc, you can see which properties you can set here https://help.qlik.com/sense/en-us/developer/index.html#../Subsystems/EngineAPI/Content/GenericObject/PropertyLevel/HyperCubeDef.htm#NxDimension

             

            But it would be something like

             

            "qDimensions": [{
             "qDef": "FieldName",
              "qNullSuppression": true
            }, {
             "qDef": "FieldName2",
             "qNullSuppression": true
            }]
            
              • Re: Qlik sense extension load data without dimension
                Bryan Sng

                Hmm both sounds like viable solution, let me give it a shot and see which suits me better, thanks!

                • Re: Qlik sense extension load data without dimension
                  Bryan Sng

                  Hmm this does work but alas it will add the specified dimensions into the extension properties panel -> dimension section. So I guess its like some sort of predefined dimension rather than manually adding dimension in. Ultimately though, there are still many dimensions in the extension properties which our client do not want. I guess I may have to try out more in depth with Øystein Kolsrud solution, do you have any insight regarding why I could not find GetTableData method in the app object as replied above?

                    • Re: Qlik sense extension load data without dimension
                      Erik Wetterberg

                      Hi Bryan,

                      I'm not totally sure what you are after. You could do this by setting up the field you want one or several qListObjectDef in your initialProperties in the extension. This is what Horizontal Listbox does, and many other extensions. If you want the user to be able to select the field in the properties panel, you should add a property panel definition like in Horizontal Listbox too.

                       

                      The other way available to you is to use the qlik library and the method createList. To use that in an extension you first need to get a reference to the current app with the call qlik.currApp(this). Note that if you use this method, the callback function you provide for the createList method will be called not only once, but every time data changes (that is when the user makes a selection). If you need sveral lists, you can call createList multiple times.

                       

                      If you do not want to be notified any more of selection changes you should use the method destroySessionObject. The id you should use would be in the createList reply.

                       

                      Hope this helps

                       

                      Erik

                        • Re: Qlik sense extension load data without dimension
                          Bryan Sng

                          Hello Erik, thanks for the additional insight, to clarify, basically my extension need to display a map.

                           

                          When user click on a point in map, it is suppose to get information from the data model based on the click source.

                          (E.g. I click on eiffel tower, it will display opening hours, height, description, how to get there, etc.)

                          These information are loaded currently into my data model.

                           

                          In order to display these information, I can add each of these data as individual dimension

                          (e.g. opening hours - 1 dimension, height - 1 dimension, description - 1 dimension, etc)

                          This is do able but there are too many dimensions to be added (we got like 20+ information to display).

                           

                          As such, we would like to be able to retrieve information directly from the app data model without going through dimensions.

                           

                          qListObjectDef and qHyperCubeDef does work but they will add that 20+ dimensions to my extensions.

                          I need to find a way to get data without using dimensions.

                            • Re: Qlik sense extension load data without dimension
                              Alexander Karlsson

                              Hmm, I did something similar for my Google Maps extensions.

                              You could perhaps even get away with just having a single expression?

                               

                              In the expression you could just build up a html formatted string and insert that into your popup.

                              Example: ='Location: ' & Only(LocationName) & '<br>' & 'Value: ' & Sum(Value)
                              It will then calculate all those values for you for that single dimensional value.

                              • Re: Qlik sense extension load data without dimension
                                Erik Wetterberg

                                Feels like createCube is the way to go. It allows you to send in a number of dimensions and measures, just make sure that you set the qWidth in qInitialDataFetch high enough. Since you only want to get the data once, and not set up a subscription, you should call destroySessionObject once you have got what you want.

                                 

                                So you would call the following:

                                1. qlik.currApp(this) (you could do this only once and save the app object)
                                2. make sure selection state is what you want, possibly make a selection
                                3. createCube
                                4. in the callback from createCube: destroySessionObject

                                Hope this helps.

                                 

                                Erik

                                  • Re: Qlik sense extension load data without dimension
                                    Bryan Sng

                                    This solution looks very promising as indeed I am now able to retrieve data without specifying dimension in my extension. There is a catch now as you mentioned, I need to set the qInitialDataFetch high enough. However the information that I need to retrieve is about 8000+ records. I read elsewhere that qlik sense initial data load seems to cap at around 1000 records. The following URL: How to use Backend API from Mashups? poster does have the same problem as me but with no solution, do you guys have any?

                                     

                                    Alternatively, is there anyway to get only a single record based on a criteria? Since my requirement for this case is to display building information given a building id.

                                      • Re: Qlik sense extension load data without dimension
                                        Erik Wetterberg

                                        Good that you are moving forward!

                                         

                                        Perhaps you could try something like:

                                        app.field("BUILDID").selectValues(["110033445566"],false,true);
                                        

                                        before you create the hypercube to get the data.

                                         

                                        Erik

                                          • Re: Qlik sense extension load data without dimension
                                            Bryan Sng

                                            Hmm, I tried the selectValues method and a little bit strange, it's working 90% of the time (90% of the time it retrieve data based on my criteria, 10% of the time it retrieve all 8000+ records). Below is an extract of my codes:

                                             

                                                var datas = [];

                                                var app = qlik.currApp(this);

                                             

                                                app.field("building_id").selectValues([41838777],false,true);

                                             

                                                app.createCube({

                                                  qDimensions: qDimensions,

                                                  qMeasures: [],

                                                  qInitialDataFetch: [{

                                                    qWidth: 10,

                                                    qHeight: 500

                                                  }]

                                                }, function(reply) {

                                                  $.each(reply.qHyperCube.qDataPages[0].qMatrix, function(key, value) {

                                                    datas.push(value);

                                                  });

                                             

                                                  app.destroySessionObject(reply.qInfo.qId);

                                                  console.log(datas); // 90% filtered, 10% full

                                                });


                                            Additionally, I realise what selectValues does is selecting that criteria in qlik sense current selection.

                                            I'm just thinking if I already have some selections from other components, i would probably be retrieving data based on the combined criteria. Hmm, is there a way to create an app such that it does not use the current app to retrieve the data but using a temporary app instead so that I will not be messing with the current app selection?


                              • Re: Qlik sense extension load data without dimension
                                Erik Wetterberg

                                Hi,

                                There is a timing issue here apparently. Try:

                                 

                                app.field(...).selectValues(...).then(function(){

                                  app.createCube(...);

                                });

                                 

                                Should fix that problem...

                                 

                                Yes, it would affect selection state. You could restore it with app.back() after you get the data.

                                 

                                Another possible solution (which I haven't tried, so I can not promise you that it works) is using an alternate state. You could create it with app.addAlternateState and then use it both when you get the field and when you create the cube.

                                 

                                Erik

                                  • Re: Qlik sense extension load data without dimension
                                    Bryan Sng

                                    Hello Erik, you did it! addAlternateState was the way to go.

                                    I am now able to get data from the data model without using dimension.

                                    Here is an extract of my working codes in case any one have the same issue as me.

                                    Once again, totally appreciate your help on this issue, thanks!

                                     

                                        getBackendData( [ 'building_id', 'product_name' ], 'building_id', [ 1234567 ] ).done(function(datas) {

                                          var match = datas[0];

                                          console.log(match); // this contains building id and product name information

                                        });

                                     

                                      function getBackendData(dimensions, fieldName, fieldValues) {

                                        var qDimensions = [];

                                     

                                        $.each(dimensions, function(index, dimension) {

                                          qDimensions.push({ qDef : { qFieldDefs : [dimension] } });

                                        });

                                     

                                        var datas = [];

                                        var deferred = $.Deferred();

                                        var alternateStateName = 'demo123832'; // some unique name would be good here

                                     

                                        var app = qlik.currApp();

                                     

                                        app.addAlternateState(alternateStateName).then(function() {

                                          app.field(fieldName, alternateStateName).selectValues(fieldValues, false, true).then(function() {

                                            app.createCube({

                                              qStateName: alternateStateName,

                                              qDimensions: qDimensions,

                                              qMeasures: [],

                                              qInitialDataFetch: [{

                                                qWidth: 10,

                                                qHeight: 500

                                              }]

                                            }, function(reply) {

                                              $.each(reply.qHyperCube.qDataPages[0].qMatrix, function(key, value) {

                                                datas.push(value);

                                              });

                                     

                                              app.destroySessionObject(reply.qInfo.qId).then(function() {

                                                app.removeAlternateState(alternateStateName);

                                              });

                                     

                                              deferred.resolve(datas);

                                            });

                                          });

                                        });

                                     

                                        return deferred;

                                      }

                                     

                                    P.S. thanks to all other contributors too!

                                      • Re: Qlik sense extension load data without dimension
                                        Erik Wetterberg

                                        Congratulations!

                                        Your are the first one I know to use Alternate states in a Qlik Sense extension. Is this something you could share, for example at Branch?? If not I would be interested in a copy myself.

                                         

                                        Erik

                                        • Re: Qlik sense extension load data without dimension
                                          Bryan Sng

                                          For anyone who is using this solution, I just want to add that this solution will not work if user is already in selection mode.

                                           

                                          For example you are selecting an item from a table and you are using the selected data to retrieve some other data from the data store, the selectValues method will fail because selectValues cannot execute when application is already in the selection mode context.

                                           

                                          I am using another solution by openApp instead. This also allow us to have 2 different selection container that does not conflict with each other although the clean up is having a little issue. A separate topic was opened instead:

                                           

                                          qlik.openApp and qlik.close

                                            • Re: Qlik sense extension load data without dimension
                                              Bryan Sng

                                              For anyone following this thread, I realise addAlternateState has more problem, it turn out that whenever there is a current selection that intersect with the result from createCube, the result from createCube will be filtered to the current selection.

                                               

                                              Here's an example:

                                               

                                              Assuming there is no selection at qlik selection bar, the following codes will return 4 product ids:

                                              1111

                                              2222

                                              3333

                                              4444

                                               

                                              /****************

                                              var temp1 = qlik.currApp();

                                              var sttate = '123456890';

                                               

                                              temp1.addAlternateState(sttate).then(function() {

                                                temp1.field('Postal Code', sttate).clear();

                                               

                                                temp1.field('Postal Code', sttate).selectValues([109441, 328958], false, true).then(function() {

                                                  temp1.createCube({

                                                    qStateName: sttate,

                                                    qDimensions: [{ qDef : { qFieldDefs : ['Product ID'] } }],

                                                    qMeasures: [],

                                                    qInitialDataFetch: [{

                                                      qTop: 0,

                                                      qLeft: 0,

                                                      qWidth: 1,

                                                      qHeight: 10000

                                                    }]

                                                  }, function(reply) {

                                                    console.log(reply.qHyperCube.qDataPages[0].qMatrix);

                                               

                                                    temp1.destroySessionObject(reply.qInfo.qId).then(function() {

                                                      temp1.removeAlternateState(sttate);

                                                    });     

                                                  });

                                                });

                                              });

                                              ****************/


                                              Now assuming there is a selection of product id 1111 at the qlik selection bar,

                                              the same code will return just 1 product id:


                                              1111


                                              It's not as expected as alternate state is suppose to be a separate container, anyone got any ideas?

                                              Just for info I'm exploring alternate state again because openApp strategy cannot support multiple users.


                                              Finally, just to reiterate, the main objective is to query data from qlik without using dimension, just in case anyone got any more better strategy after the release of 2.0.1



                                                • Re: Qlik sense extension load data without dimension
                                                  Erik Wetterberg

                                                  When you create an alternate state it will start with a copy of the default state, that is intentional.

                                                   

                                                  Erik

                                                    • Re: Qlik sense extension load data without dimension
                                                      Bryan Sng

                                                      Hmm interesting, is there anyway I can clear all the selection in the alternate state?

                                                       

                                                      I know for sure I cannot use app.clearAll() because that will wipe out my qlik selection bar instead of the alternate state.

                                                       

                                                      Alternatively I think i can get the extension dimensions via layout, then do a loop on each of the dimension before executing app.field(dimension, stateName).clear() on them but it seems cumbersome.

                                                       

                                                      Additionally, is there anyway to perform app.field(...).clear and app.field(...).selectValues without messing with the qlik selection bar?

                                                       

                                                      I'm trying to do some clear and selectValues but I do not want the user to see them when clicking on the previous selection at the qlik selection bar.

                                                       

                                                      Thanks!

                                                        • Re: Qlik sense extension load data without dimension
                                                          Erik Wetterberg

                                                          Hi,

                                                          You should be able to clear selections in an alternate state with clearAll() method, but I'm afraid the state parameter is missing from that call. This is a bug, I'll see to it that it gets fixed for the next version (probably 2.1).

                                                           

                                                          Erik

                                                            • Re: Qlik sense extension load data without dimension
                                                              Bryan Sng

                                                              Sounds great to me! I will temporarily wrap those cumbersome calls and wait for the fix in 2.1.

                                                              Hmm do you have any ideas about the selection history?

                                                              Any methods not to store them when clear or selectValues (maybe like an optional parameter)?

                                                               

                                                              Oh, recently I been looking more into engine API.

                                                              Then I play around with the protocol tester and realise getTableData (recommend earlier by Øystein Kolsrud) is able to get data directly too.

                                                              However there is no filter I can provide as a params, do you have any advice to get data directly using engine API?

                                                               

                                                              Hmm, if only there is some way I can get data from qlik application data store like SQL, that would be super fantastic!

                                                                • Re: Qlik sense extension load data without dimension
                                                                  Bryan Sng

                                                                  Hmm I have been doing some testing and realise the following:

                                                                   

                                                                  Suppose I have an empty extension with only a paint method.

                                                                   

                                                                      paint: function($element, layout) {

                                                                         console.log(qlik.currApp());

                                                                      }

                                                                   

                                                                  Then I create a sheet with that extension and run it.

                                                                  The app start off with 0 selection.

                                                                   

                                                                  I use the search function from the selection bar and do any searching (e.g. Country = USA)

                                                                  It will show "Country: USA" at the selection bar.

                                                                  Qlik selection bar now has 1 history item which is correct.

                                                                   

                                                                  Now I execute the following snippet at the console window after registering qlik.currApp() as temp1.

                                                                   

                                                                  var sttate = '1234567890';

                                                                   

                                                                  temp1.addAlternateState(sttate).then(function() {

                                                                    temp1.field('Country', sttate).clear();

                                                                    temp1.field('Country', sttate).selectValues(['Australia'], true, true);

                                                                  });


                                                                  The selection history at qlik selection bar become 3!

                                                                  I'm assuming clear and selectValues are contributing to the selection history although they are at an alternate state.


                                                                  Now when I try to do a back to previous selection action, those 2 extra history items are duplicating the initial selection (Country: USA).


                                                                  Current selection: Country: USA

                                                                  1st click on previous: Country: USA

                                                                  2nd click on previous: Country: USA

                                                                  3rd click on previous: No selections applied


                                                                  Any ideas how to prevent alternate state from recording history?


                                                                    • Re: Qlik sense extension load data without dimension
                                                                      Erik Wetterberg

                                                                      Yes, you are right, there is only one stack for back/forward, so selections in alternate state will affect this stack. As far as I know there is nothing you can do about it.

                                                                       

                                                                      Erik

                                                                        • Re: Qlik sense extension load data without dimension
                                                                          Bryan Sng

                                                                          Erm... that doesn't sound like good news because my extension is stuck with the current selection permanently.

                                                                           

                                                                          Reason is because whenever user click previous, the selection at selection bar trigger a paint event which cause my extension to get data for other dimension via createCube in an alternate state. The getting data part will add the selection history.

                                                                           

                                                                          This result in a clicking previous, adding history item, clicking more previous, adding more history item... loop.

                                                                           

                                                                          Hmm, not sure whether you have seen my alternative at qlik.openApp and qlik.close

                                                                           

                                                                          I was aiming to open an application in a separate context.

                                                                          Meaning to be able to do selectValues, getting data from there via createCube and cleanup via close without affecting the current app.

                                                                          All I really need is openApp to open in a different context.

                                                                      • Re: Qlik sense extension load data without dimension
                                                                        Øystein Kolsrud

                                                                        The getTableDate method is just intended for accessing the raw data. If you are looking for Qlik Sense to provide features beyond that, then hypercubes or list objects are definitely what you should be looking at.

                                                                          • Re: Qlik sense extension load data without dimension
                                                                            Bryan Sng

                                                                            Yeah, that's where createCube come in and in order to have additional filters beyond the current selection, alternate state + selectValues looks like the only way to go for now but it's having previous selection issue.

                                                                             

                                                                            OpenApp method to open the same application using another identity just for the sake of getting data is unfortunately not working or that solution would be ample enough.

                                                                             

                                                                            Kind of stuck for now