Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
I have the following code which returns a promise object. In inspector it goes from $$state 0 to $$state 1 and then shows the values of the filters I am trying to return to a variable. Anytime I try to return that value it doesn't work because its a promise that I assume has not been resolved yet. What can I do to get that value and wrap my head around the promise structure. (Apologies if this is a stupid question).
const getFieldList = function () {
var defer = $q.defer();
app.getList( 'FieldList', function (items) {
defer.resolve( items.qFieldList.qItems.map( function (item) {
return {
value: item.qName,
label: item.qName
}
}));
});
return defer.promise;
};
let test = function () {
return getFieldList().then(function (items) {
return items;
});
};
console.log(test().$$state.value);
In that case, it can be even simpler:
app.getList('FieldList').then(function (result) {
//here the promise had already resolved
dropdownHTMLCode = '<select>';
result.layout.qFieldList.qItems.forEach(function (row) {
dropdownHTMLCode += '<option value=' + row.qName+ '>' + row.qName + '</option>';
});
dropdownHTMLCode = '</select>';
console.log(dropdownHTMLCode );
}
or if u want function to return this string:
function getHTMLcode() {
return new Promise(function(resolve, reject) {
app.getList('FieldList').then(function (result) {
//here the promise had already resolved
dropdownHTMLCode = '<select>';
result.layout.qFieldList.qItems.forEach(function (row) {
dropdownHTMLCode += '<option value=' + row.qName+ '>' + row.qName + '</option>';
});
dropdownHTMLCode = '</select>';
resolve(dropdownHTMLCode);
});
});
}
getHTMLcode().then(function (dropdownHTMLCode) {console.log(dropdownHTMLCode);});
when u use console.log, it does not wait for the promise to resolve
how about using this approach:
const getFieldList = function () {
return(app.getList('FieldList'))
}
getFieldList.then(function(result) {
console.log(result);
//or do any prcoessing to the result
});
or if u want
const getFieldList = function () {
return new Promise(function(resolve, reject) {
app.getList('FieldList').then (function(result) {
var items= //process the items from the result
resolve(items);
}
});
getFieldList.then(function(items) {
console.log(items);
});
@oz_moyal That makes a lot of sense. I want to add the results into a drop down with code like by assigning the results to a variable(in this case test)
dropdownHTMLCode = '<select>' + test.foreach((e){ return '<option value=' + e.value + '>' + e.label + '</option>'; }) + '</select>';
The problem is when this runs I don't think the promise has completed assigning the values to test so the drop down is empty.
In that case, it can be even simpler:
app.getList('FieldList').then(function (result) {
//here the promise had already resolved
dropdownHTMLCode = '<select>';
result.layout.qFieldList.qItems.forEach(function (row) {
dropdownHTMLCode += '<option value=' + row.qName+ '>' + row.qName + '</option>';
});
dropdownHTMLCode = '</select>';
console.log(dropdownHTMLCode );
}
or if u want function to return this string:
function getHTMLcode() {
return new Promise(function(resolve, reject) {
app.getList('FieldList').then(function (result) {
//here the promise had already resolved
dropdownHTMLCode = '<select>';
result.layout.qFieldList.qItems.forEach(function (row) {
dropdownHTMLCode += '<option value=' + row.qName+ '>' + row.qName + '</option>';
});
dropdownHTMLCode = '</select>';
resolve(dropdownHTMLCode);
});
});
}
getHTMLcode().then(function (dropdownHTMLCode) {console.log(dropdownHTMLCode);});
@oz_moyal I must be missing something. I tried to render the drop down and all I get is undefined or if I move everything into the promise I get nothing returned. Its like the page is rendering faster than the promise.
define(['jquery', 'qlik', 'css!./Dane-Selections_Applier.css', './properties', 'ng!$q'], function ($, qlik, cssContent, properties, $q) {
return {
definition: properties,
paint: function ($element, layout, jquery,properties) {
app = qlik.currApp();
const getFieldList = function () {
var defer = $q.defer();
app.getList( 'FieldList', function (items) {
defer.resolve( items.qFieldList.qItems.map( function (item) {
return {
value: item.qName,
label: item.qName
}
}));
});
return defer.promise;
};
var dropdownHTMLCode;
getFieldList().then(function (result) {
//here the promise had already resolved
dropdownHTMLCode = '<select>';
result.layout.qFieldList.qItems.forEach(function (row) {
dropdownHTMLCode += '<option value=' + row.qName+ '>' + row.qName + '</option>';
});
dropdownHTMLCode += '</select>';
});
var buttonHTMLCode = '<button name="ApplySelections" id="applySelections-'+layout.qInfo.qId+'" class="applySelections">Apply Selections'+((layout.field=='')?'':' to '+ layout.field)+'</button>';
var textboxHTMLCode = '<textarea id="selectionsTextboxArea-'+layout.qInfo.qId+'" style="height: 10%;width: 90%;font-size: 10px;" placeholder="test"></textarea>';
$element.html(dropdownHTMLCode + '<table style="height:10%;text-align: center;"><tr><td style="width:20%;">'+buttonHTMLCode+'</td><td style="width:80%;">'+textboxHTMLCode+'</td></tr></table>');
addOnActivateButtonEvent($element,layout,app);
}
};
});
//Helper funciton for adding on a "qv-activate" event of button/link
var addOnActivateButtonEvent = function ($element,layout,app) {
$("#applySelections-"+layout.qInfo.qId).on('qv-activate', function () {
console.log(0);
var selectionsInput = document.getElementById("selectionsTextboxArea-"+layout.qInfo.qId).value.split('\n');
selectionsInput = selectionsInput.filter(function(n){ return n != "" });
selections = layout.isNumeric ? selectionsInput.map(function(item){return parseFloat(item);}) : selectionsInput;
console.log('Selections to be applied are:', selections);
app.field(layout.field).selectValues(selections, true,true);
});
};
u can't use dropdownHTMLCode
out of the promise , it will not have the value there
u need to move all this lines:
var buttonHTMLCode = '<button name="ApplySelections" id="applySelections-'+layout.qInfo.qId+'" class="applySelections">Apply Selections'+((layout.field=='')?'':' to '+ layout.field)+'</button>'; var textboxHTMLCode = '<textarea id="selectionsTextboxArea-'+layout.qInfo.qId+'" style="height: 10%;width: 90%;font-size: 10px;" placeholder="test"></textarea>'; $element.html(dropdownHTMLCode + '<table style="height:10%;text-align: center;"><tr><td style="width:20%;">'+buttonHTMLCode+'</td><td style="width:80%;">'+textboxHTMLCode+'</td></tr></table>'); addOnActivateButtonEvent($element,layout,app);
after this line:
dropdownHTMLCode += '</select>';
so it is inside the "then" function block.
please also add after this line:
console.log(dropdownHTMLCode); so u can test its content in the console.
@oz_moyal I gave that a try earlier and just redid it now with the added console.log. It isn't even showing up and the extension container is empty. I figure its something stupid like a missed parenthesis or something but the error catching isn't great in qlik. Side note - I really appreciate you trying to help me with this.
define(['jquery', 'qlik', 'css!./Dane-Selections_Applier.css', './properties', 'ng!$q'], function ($, qlik, cssContent, properties, $q) {
return {
definition: properties,
paint: function ($element, layout, jquery,properties) {
app = qlik.currApp();
const getFieldList = function () {
var defer = $q.defer();
app.getList( 'FieldList', function (items) {
defer.resolve( items.qFieldList.qItems.map( function (item) {
return {
value: item.qName,
label: item.qName
}
}));
});
return defer.promise;
};
getFieldList().then(function (result) {
//here the promise had already resolved
var dropdownHTMLCode = '<select>';
result.layout.qFieldList.qItems.forEach(function (row) {
dropdownHTMLCode += ('<option value="' + row.qName+ '">' + row.qName + '</option>');
});
dropdownHTMLCode += '</select>';
var buttonHTMLCode = '<button name="ApplySelections" id="applySelections-'+layout.qInfo.qId+'" class="applySelections">Apply Selections'+((layout.field=='')?'':' to '+ layout.field)+'</button>';
var textboxHTMLCode = '<textarea id="selectionsTextboxArea-'+layout.qInfo.qId+'" style="height: 10%;width: 90%;font-size: 10px;" placeholder="test"></textarea>';
$element.html(dropdownHTMLCode + '<table style="height:10%;text-align: center;"><tr><td style="width:20%;">'+buttonHTMLCode+'</td><td style="width:80%;">'+textboxHTMLCode+'</td></tr></table>');
addOnActivateButtonEvent($element,layout,app);
console.log(dropdownHTMLCode);
console.log('test');
});
}
};
});
It seem to me the issue is with
const getFieldList = function () {
I do not know if return the promise and the values properly, i wrote it differently, in what i sent u.
can u try to put this code in the beginning paint function, and check the console log:
app.getList('FieldList').then(function (result) {
//here the promise had already resolved
dropdownHTMLCode = '<select>';
result.layout.qFieldList.qItems.forEach(function (row) {
dropdownHTMLCode += '<option value=' + row.qName+ '>' + row.qName + '</option>';
});
dropdownHTMLCode += '</select>';
console.log(dropdownHTMLCode );
}
@oz_moyal just wanted to let you know that worked like a charm. Thank you so much.