Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hello all,
I'm creating a mashup using hypercube.
I'm trying to use a hypercube to get value 'Year', from a expression using the Qlik Engine. After that, I want to make an automatic selection on the field 'Year'.
So ok, my hypercube is working and calling my callback function. Then I set my selection on the right field. And it works.
But I realized that the callback function keeps getting called after every selection made on the mashup. Since my data doesn't change, I don't want it to happen. It's unecessary.
I managed this issue by:
1. Placing a flag like:
var hypercubeDone = false;
function callback(reply, app) {
if(hypercube) {
return;
}
// do some stuff
hypercubeDone = true;
}
in my JavaScript file.
But that doesn't solve my problem of calling this method multiple times. So I tried another solution...
2. Destroying the hypercube after the call:
But don't know if this is a good practice. So I tried to find another way.
I don't want this to happen, since it is not necessary. Is there a right way to prevent this?
Thanks!!
Checked this up: if you use qlik.js (AKA capability api's, mashup API) to open the app, you will find the enigmaModel at app.model.enigmaModel.
So the call will be:
app.model.enigmaModel.evaluate('1+1').then(function(reply){
console.log("evaluated:",reply);
});
Hope this helps
Erik Wetterberg
Using hypercube, I can get a different callback for each expression, but with 'Evaluate' I can't, since it's a WebSocket and the only event I get from sending a request is
ws.onmessage = function(){};
Ideal would be if there's something like
ws.send(JSON.stringify(expressionData), function(response){
console.log("hey, this is the response: ", response);
});
Should a lot of ifs or switch/case inside onmessage = "" or there is another way to do this?
Thanks!
Hi,
You should get hold of the enigmaModel, which has an evaluate method defined that returns a promise. Basically enigmajs wraps all QIX methods this way, and so solves the problem of connecting request and response for you.
In an extension it would be something like:
model.enigmaModel.app.evaluate('1+1').then(function(reply){
console.log(reply);
})
Haven't tried in a mashup, but something like:
app.enigmaModel.evaluate('1+1').then(function(reply){
console.log(reply);
})
You might need to use the console to find the object that has the evaluate method defined.
Hope this helps
Erik Wetterberg
Hey there!
This sounds really good and straightforward to make some generic functions across a mashup. I'll look deep into it and post here if solves my issue, with my code as well
Thanks Erik!
Checked this up: if you use qlik.js (AKA capability api's, mashup API) to open the app, you will find the enigmaModel at app.model.enigmaModel.
So the call will be:
app.model.enigmaModel.evaluate('1+1').then(function(reply){
console.log("evaluated:",reply);
});
Hope this helps
Erik Wetterberg
This is just great for front end development. Thanks for the tip!
Just use the promise instead of the callback.
app.createCube({
// stuff
}, function(layout) { //this is the callback, just dont use it })
instead do this
app.createCube({
// stuff
}).then(function(object) { // here you'll get the object, which has layout on it, and this will only run once })
Hi Francis,
How can I retrieve the value of the expression in the promise ?
What code should I write ?
When I look at the "object" in the chrome debug, I don't find the value of the expression.
app.createCube({
"qInitialDataFetch": [
{
"qHeight": 20,
"qWidth": 1
}
],
"qDimensions": [],
"qMeasures": [
{
"qDef": {
"qDef": "max({$<[Year Month]={$(=maxstring([Year Month]))}>}Month)"
},
"qLabel": "GetPlatform",
"qLibraryId": null,
"qSortBy": {
"qSortByState": 0,
"qSortByFrequency": 0,
"qSortByNumeric": 0,
"qSortByAscii": 1,
"qSortByLoadOrder": 0,
"qSortByExpression": 0,
"qExpression": {
"qv": " "
}
}
}
],
"qSuppressZero": false,
"qSuppressMissing": false,
"qMode": "S",
"qInterColumnSortOrder": [],
"qStateName": "$"
}).then(function(object) {
// here you'll get the object, which has layout on it, and this will only run once
What shoul I do write here ?
});
Thanks !
Paul
Hi Paul,
Don't use a Hypoercube if you only want one expression evaluated, use a ValueExpression instead. Also note that createCube will create a subscription, so the expression will be recalculated when there are changes in selection state that affects the result. By using the promise instead of the callback you will not be notified, by the calculation will be made anyhow. Evaluate is really better for a one-time calculation.
Hope this helps
Erik Wetterberg