Last active
March 6, 2018 00:33
-
-
Save theredpea/45a5fd5b9e784ae1455388ce06dd4c0c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LOAD * INLINE [ | |
Val | |
0022 | |
0023 | |
0024 | |
C001 | |
C002 | |
G001 | |
SF01 ]; | |
require('qlik').currApp().model.engineApp.getFieldDescription('Val') | |
{"method":"GetFieldDescription","handle":1,"params":["Val"],"delta":false,"jsonrpc":"2.0","id":25} | |
//Notice results no tags; qTags is empty; no qIsNumeric | |
{"jsonrpc":"2.0","id":25,"result":{"qReturn":{"qInternalNumber":6,"qName":"Val","qSrcTables":["INLFED"],"qCardinal":7,"qTotalCount":7,"qPossibleCount_OBSOLETE":-1,"qTags":[]}}} | |
//Therefore get the results, some can be qNum, some cannot: | |
require('qlik').currApp().field('Val').getData() | |
{"method":"GetLayout","handle":10,"params":[],"delta":true,"jsonrpc":"2.0","id":28} | |
{"jsonrpc":"2.0","id":28,"delta":true,"result":{"qLayout":[{"op":"add","path":"/","value":{"qInfo":{"qId":"MUcshDmDt","qType":"mashup"},"qSelectionInfo":{},"qListObject":{"qSize":{"qcx":1,"qcy":7},"qDimensionInfo":{"qFallbackTitle":"Val","qApprMaxGlyphCount":4,"qCardinal":7,"qSortIndicator":"N","qGroupFallbackTitles":["Val"],"qGroupPos":0,"qStateCounts":{"qLocked":0,"qSelected":0,"qOption":7,"qDeselected":0,"qAlternative":0,"qExcluded":0,"qSelectedExcluded":0,"qLockedExcluded":0},"qTags":[],"qDimensionType":"D","qGrouping":"N","qNumFormat":{"qType":"U","qnDec":0,"qUseThou":0},"qIsAutoFormat":true,"qGroupFieldDefs":["Val"],"qMin":0,"qMax":0,"qAttrExprInfo":[],"qAttrDimInfo":[]},"qExpressions":[],"qDataPages":[{"qMatrix":[[{"qText":"C001","qNum":"NaN","qElemNumber":3,"qState":"O","qFrequency":"1"}],[{"qText":"C002","qNum":"NaN","qElemNumber":4,"qState":"O","qFrequency":"1"}],[{"qText":"G001","qNum":"NaN","qElemNumber":5,"qState":"O","qFrequency":"1"}],[{"qText":"SF01","qNum":"NaN","qElemNumber":6,"qState":"O","qFrequency":"1"}],[{"qText":"0022","qNum":22,"qElemNumber":0,"qState":"O","qFrequency":"1"}],[{"qText":"0023","qNum":23,"qElemNumber":1,"qState":"O","qFrequency":"1"}],[{"qText":"0024","qNum":24,"qElemNumber":2,"qState":"O","qFrequency":"1"}]],"qTails":[],"qArea":{"qLeft":0,"qTop":0,"qWidth":1,"qHeight":7}}]}}}]}} | |
[ | |
[ | |
{ | |
"qText": "C001", | |
"qNum": "NaN", | |
"qElemNumber": 3, | |
"qState": "O", | |
"qFrequency": "1" | |
} | |
], | |
[ | |
{ | |
"qText": "C002", | |
"qNum": "NaN", | |
"qElemNumber": 4, | |
"qState": "O", | |
"qFrequency": "1" | |
} | |
], | |
[ | |
{ | |
"qText": "G001", | |
"qNum": "NaN", | |
"qElemNumber": 5, | |
"qState": "O", | |
"qFrequency": "1" | |
} | |
], | |
[ | |
{ | |
"qText": "SF01", | |
"qNum": "NaN", | |
"qElemNumber": 6, | |
"qState": "O", | |
"qFrequency": "1" | |
} | |
], | |
[ | |
{ | |
"qText": "0022", | |
"qNum": 22, | |
"qElemNumber": 0, | |
"qState": "O", | |
"qFrequency": "1" | |
} | |
], | |
[ | |
{ | |
"qText": "0023", | |
"qNum": 23, | |
"qElemNumber": 1, | |
"qState": "O", | |
"qFrequency": "1" | |
} | |
], | |
[ | |
{ | |
"qText": "0024", | |
"qNum": 24, | |
"qElemNumber": 2, | |
"qState": "O", | |
"qFrequency": "1" | |
} | |
] | |
] | |
//Therefore making a selection of just text Values, will not do what you expect: | |
//Will not select Val=0024, will only Val=G001 , because I only use text: | |
require('qlik').currApp().field('Val').selectValues(['0024', 'G001']) | |
//I can fix 24, but then what do I pass for the text value? | |
require('qlik').currApp().field('Val').selectValues([24, ??]) | |
//My only choice is to do a mixed selection, which Qlik handles fine: | |
require('qlik').currApp().field('Val').selectValues([24, 'G001']) | |
//Becomes: | |
{"method":"SelectValues","handle":9,"params":[[{"qIsNumeric":true,"qNumber":24},{"qText":"G001"}],false,false],"delta":false,"jsonrpc":"2.0","id":48} | |
//And the result is what I expect: | |
//Current Selections bar shows those 2 values are selected | |
//Val -> 2 of 7 | |
// I confirmed against the specific business case where I was seeing an issue here | |
// that an *empty qTags array* is a symptom of a field that is inconsistent/ambiguous (i.e. in this case, has some field values with qText only, but some field values have qNum) | |
//And demonstrated that a workaround if you use selectMatch. | |
//Yep..., "you would not use selectValues if qIsNumeric is anything other than true" | |
//At first thought that the interface of the values passed into selectValues, was *same* as interface of returned data | |
//but not | |
//returned data looks like this: | |
//i.e. from GetListObjectData or the GetLayout on a CreateSessionObject List for a getField call | |
//On a filterpane (GetListObjectData) | |
//{"method":"GetListObjectData","handle":8,"params":["/qListObjectDef",[{"qTop":0,"qLeft":0,"qHeight":7,"qWidth":1}]],"delta":true,"jsonrpc":"2.0","id":27} | |
//{"jsonrpc":"2.0","id":27,"delta":true,"result":{"qDataPages":[{"op":"add","path":"/","value":[{"qMatrix":[[{"qText":"C001","qNum":"NaN","qElemNumber":3,"qState":"O"}],[{"qText":"C002","qNum":"NaN","qElemNumber":4,"qState":"O"}],[{"qText":"G001","qNum":"NaN","qElemNumber":5,"qState":"O"}],[{"qText":"SF01","qNum":"NaN","qElemNumber":6,"qState":"O"}],[{"qText":"0022","qNum":22,"qElemNumber":0,"qState":"O"}],[{"qText":"0023","qNum":23,"qElemNumber":1,"qState":"O"}],[{"qText":"0024","qNum":24,"qElemNumber":2,"qState":"O"}]],"qTails":[],"qArea":{"qLeft":0,"qTop":0,"qWidth":1,"qHeight":7}}]}]}} | |
//{"qText":"C001","qNum":"NaN","qElemNumber":3,"qState":"O"} | |
//On a field I called : require('qlik').currApp().field('Val').getData() (which it turns out CreateSessionObject and | |
//{"jsonrpc":"2.0","id":30,"delta":true,"result":{"qLayout":[{"op":"add","path":"/","value":{"qInfo":{"qId":"MUdYbzyW","qType":"mashup"},"qSelectionInfo":{},"qListObject":{"qSize":{"qcx":1,"qcy":7},"qDimensionInfo":{"qFallbackTitle":"Val","qApprMaxGlyphCount":4,"qCardinal":7,"qSortIndicator":"N","qGroupFallbackTitles":["Val"],"qGroupPos":0,"qStateCounts":{"qLocked":0,"qSelected":0,"qOption":7,"qDeselected":0,"qAlternative":0,"qExcluded":0,"qSelectedExcluded":0,"qLockedExcluded":0},"qTags":[],"qDimensionType":"D","qGrouping":"N","qNumFormat":{"qType":"U","qnDec":0,"qUseThou":0},"qIsAutoFormat":true,"qGroupFieldDefs":["Val"],"qMin":0,"qMax":0,"qAttrExprInfo":[],"qAttrDimInfo":[]},"qExpressions":[],"qDataPages":[{"qMatrix":[[{"qText":"C001","qNum":"NaN","qElemNumber":3,"qState":"O","qFrequency":"1"}],[{"qText":"C002","qNum":"NaN","qElemNumber":4,"qState":"O","qFrequency":"1"}],[{"qText":"G001","qNum":"NaN","qElemNumber":5,"qState":"O","qFrequency":"1"}],[{"qText":"SF01","qNum":"NaN","qElemNumber":6,"qState":"O","qFrequency":"1"}],[{"qText":"0022","qNum":22,"qElemNumber":0,"qState":"O","qFrequency":"1"}],[{"qText":"0023","qNum":23,"qElemNumber":1,"qState":"O","qFrequency":"1"}],[{"qText":"0024","qNum":24,"qElemNumber":2,"qState":"O","qFrequency":"1"}]],"qTails":[],"qArea":{"qLeft":0,"qTop":0,"qWidth":1,"qHeight":7}}]}}}]}} | |
//{"qText":"C001","qNum":"NaN","qElemNumber":3,"qState":"O","qFrequency":"1"} | |
//or a more relevant example: | |
//{"qText":"0024","qNum":24,"qElemNumber":2,"qState":"O","qFrequency":"1"} | |
//Notice how "qNum" is in there! Sometimes "NaN", sometimes an actual number like 24, but the property is "qNum" | |
//This is NOT the NxCell API? ... | |
//It is the QFieldValue API: | |
//https://help.qlik.com/en-US/sense-developer/September2017/Subsystems/APIs/Content/CapabilityAPIs/FieldAPI/QFieldValue.htm/ | |
//Notice how qFrequency is optional ; the former returns it ; the latter doesnt; | |
///notice also qState is "O"; the NxCell API reminds that this stands for "Option": | |
//https://gist.github.com/theredpea/12d4c5a4d56c3acab7346a0847c1d6ae | |
//So this didnt work, thinking that I could pass *into* selectValues an object like {"qText":"0024","qNum":24,"qElemNumber":2,"qState":"O","qFrequency":"1"} | |
require('qlik').currApp().field('Val').selectValues([{qText:'0024', qNum: 24}, {qText:'G001'}]) | |
//{"method":"SelectValues","handle":10,"params":[[{"qText":"0024","qNum":24},{"qText":"G001"}],false,false],"delta":false,"jsonrpc":"2.0","id":31} | |
//the result only selected 'G001' | |
//Even this didnt work: (omitting the qText in case that was the issue | |
require('qlik').currApp().field('Val').selectValues([{ qNum: 24}, {qText:'G001'}]) | |
//{"method":"SelectValues","handle":9,"params":[[{"qNum":24},{"qText":"G001"}],false,false],"delta":false,"jsonrpc":"2.0","id":83} | |
//the result *still* only selected 'G001' | |
//But how did this work? Must be that Qlik transforms to a different engine call... | |
//require('qlik').currApp().field('Val').selectValues([24, 'G001']) | |
//Oh! Look at the call! "qNumber" is the property... | |
//{"method":"SelectValues","handle":10,"params":[[{"qIsNumeric":true,"qNumber":24},{"qText":"G001"}],false,false],"delta":false,"jsonrpc":"2.0","id":42} | |
//Specifically: | |
//{"qIsNumeric":true,"qNumber":24} | |
//What is *this* API? The QFieldValue API, above, described this API: | |
//https://help.qlik.com/en-US/sense-developer/September2017/Subsystems/APIs/Content/CapabilityAPIs/FieldAPI/QFieldValue.htm/ | |
//But the selectValues function API... what is it? apparently it is called the "FieldValue" | |
//https://help.qlik.com/en-US/sense-developer/September2017/Subsystems/EngineAPI/Content/Classes/FieldClass/Field-class-SelectValues-method.htm#FieldValue | |
//And apparently just hte property name `qNumber` (vs `qNum` ) is not the *only* difference; i.e.necessary but not sufficient to make the SelectValues call work | |
//i.e. even this will fail: | |
//require('qlik').currApp().field('Val').selectValues([{qText:'0024', qNumber: 24}, {qText:'G001'}]) | |
//notice the SelectValues call doesnt include qIsNumeric: | |
//{"method":"SelectValues","handle":10,"params":[[{"qText":"0024","qNumber":24},{"qText":"G001"}],false,false],"delta":false,"jsonrpc":"2.0","id":64} | |
//This however, is the most explicit Javascript; the resulting Engine call is almost exactly the same; | |
//that is, *both* specify qIsNumeric *and* qNumber, which is necessary and sufficient: | |
//require('qlik').currApp().field('Val').selectValues([{qText:'0024', qNumber: 24, qIsNumeric:true}, {qText:'G001'}]) | |
//{"method":"SelectValues","handle":10,"params":[[{"qText":"0024","qNumber":24,"qIsNumeric":true},{"qText":"G001"}],false,false],"delta":false,"jsonrpc":"2.0","id":86} | |
//Which works! | |
//But remember the simpler/ simplest Javascript call works (because it produces identical Engine API call to the explicit call above) | |
//i.e. simplifyign the numeric value to just a Javascript int: | |
//require('qlik').currApp().field('Val').selectValues([24, {qText:'G001'}]) | |
//And simplifying both: | |
//require('qlik').currApp().field('Val').selectValues([24, 'G001']) | |
//Of course a selectMatch will work too: | |
//require('qlik').currApp().field('Val').selectMatch('(0024|G001)') | |
//Not sure if selectMatch would be preferable for performance's sake | |
//With this test dataset; these two calls get responses exactly 2 miliseconds later than their requests: | |
//require('qlik').currApp().field('Val').selectMatch('(0023|C002)') | |
//{"method":"Select","handle":10,"params":["(0023|C002)",false],"delta":false,"jsonrpc":"2.0","id":219} | |
//require('qlik').currApp().field('Val').selectValues([23, 'C002']) | |
//{"method":"SelectValues","handle":10,"params":[[{"qIsNumeric":true,"qNumber":23},{"qText":"C002"}],false,false],"delta":false,"jsonrpc":"2.0","id":241} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment