Skip to main content
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.