Ko/modal open() how to get user's choice

I’m trying to figure out how to use ko/modal properly to display a list of some choices, and the user clicks one to indicate his choice.

return_value = require( "ko/modal" ).open( "pick an item", { items: { type: "listbox", options: { listitems: ["one", "two", "three"] }, attributes: { } } }, console.log );
alert( return_value.items );

This should reveal the field’s value, according to the documentation. It is included in console.log, but the alert() shows it as “undefined”. Any ideas?

The value is in the callback, which you are currently passing console.log for.

So the documentation…

Returns an object with key and value being the field key and the entered value, eg. {fieldName: “hello”}

…is incorrect?

If so, is there a way to get the value returned from the call to open(), so I can use it in the script?

It appears so. There is no way to have it returned, you can only get it from the callback. I don’t see why you wouldn’t be able to use that for your script?

I was assuming that the user choice would be included in the object returned by the method, regardless of whether or not a callback function was included.

So there isn’t a way for me to get a menu choice from the user and then continue processing at the same level, and instead I would have to basically compress the rest of the script’s logic into a callback? I can see that that would be OK if the remaining logic in the script was short and simple, but in my case I want to present a menu that allows the user to choose one of several categories, and for each one of those categories, present another menu, and based upon their second choice, make modifications to the current file open. So if I’m understanding this correctly, I would end up with callbacks inside of callbacks?

Welcome to JavaScript, callback all the things :slight_smile: Normally you wouldn’t ever be able to do this synchronously as it is by definition an asynchronous action. The fact that the old dialogs allowed you to do that is thanks to their legacy api’s and underlying bad practices employed by them.

As an old procedural-code dinosaur, I still find callbacks to be unwieldy and unintuitive, but I will probably get used to them with practice. (One of my goals is to really learn modern JavaScript, which seems to have grown into a substantial language far beyond the web page toy it started as.)

But I find when I try to use a simple callback, as in the example code below, when clicking the “Ok” button, nothing happens. Only the “Close” button works, but then the callback is apparently not called.

f = function() { console.log( input ); };
require( "ko/modal" ).open( "title", { input: { type: "listbox", options: { listitems: ["one", "two", "three"] } } }, f );

Is the callback itself flawed as written? I’m not sure how to access that input value.

The reason Ok doesn’t work is cause your callback throws an exception. You are accessing a variable “input” which doesn exist. This code works:

var f = function(data) { console.log( data.input ); };
require( "ko/modal" ).open( "title", { input: { type: "listbox", options: { listitems: ["one", "two", "three"] } } }, f );

So the callback argument was the key. Okay, thank you!

Be sure to have your error log open (pystderr.log) while you’re developing :slight_smile: It will usually answer why something isn’t working.

Also console.trace() is a daily tool for me.

Thanks, I’ll try those techniques. So far I’ve just been watching console.log and thus missing a lot.

I now realize why I wasn’t thinking of a callback argument: the use of console.log as the argument in our earlier examples. Presumably console.log somehow knows to display the menu choice even though it isn’t explicitly passed it as an argument?

console.log is a function, any function can be a callback. The first argument passed as the callback is the result and the first argument console.log uses is the data to be logged. So you can pass it as a callback without needing to do any additional routing. You could also pass alert for the same reason.