Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Want to see what's currently in public preview? We've pulled it all together in one place. Check it out here
cancel
Showing results for 
Search instead for 
Did you mean: 
danelooman
Creator
Creator

Value from a promise object?

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);
1 Solution

Accepted Solutions
oz_moyal
Creator
Creator

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);});

 

 

View solution in original post

8 Replies
oz_moyal
Creator
Creator

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);
  });



 

danelooman
Creator
Creator
Author

@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.  

oz_moyal
Creator
Creator

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);});

 

 

danelooman
Creator
Creator
Author

@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);
    });
};
oz_moyal
Creator
Creator

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.

danelooman
Creator
Creator
Author

@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');
				});				
        }
    };
}); 

 

oz_moyal
Creator
Creator

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 );
}

 



danelooman
Creator
Creator
Author

@oz_moyal  just wanted to let you know that worked like a charm. Thank you so much.