Problem with the Dialog API in Sugarcube 2

Hello, I’m having trouble with my Dialog API. I have a button that opens a dialog box with a textbox and then another button inside the dialog box that adds a variable to an array and moves to another passage. My problem is that when I test the game it says:

Error: <>: bad evaluation: missing ) after argument list.

This is my code:

<<button "<b>Upload Photo</b>">>
 	<<run Dialog.setup("Name your image")>>
 	<<run Dialog.wiki('<<textbox "$nametest1" "" autofocus>> <<button "[[Done|fbtemp][$photoArray.pushUnique('test2'), $upPhoto-=1]]">><<run Dialog.close()>><</button>>')>>
 	<<run Dialog.open()>>
 	<</button>>

If I take out this part:

[$photoArray.pushUnique(‘test2’), $upPhoto-=1

it works, so I think it must be a weird interaction between the parenthesis in the array.pushUnique() and the ones in the Dialog.wiki(). Or maybe I’m not putting the parenthesis were they belong.

Thanks you for your help and happy holidays.

The issue is that you are using single quotes to both:

  1. delimit the argument being passed to the Dialog.wiki('...') function.
  2. delimit the argument being passed to the <array>pushUnique('...') function.

…and that the second (inner) set of singles quotes is embedded within the first (outer) set.

You will need to escape the second (inner) set by adding a backslash character (known in this situation as an Escape character) directly before each of those single quote characters.

eg. the calling of the <array>.pushUnique() function will end up looking like…

$photoArray.pushUnique(\'test2\')
1 Like

Thanks a lot, it worked like a charm. I’ll try to learn the “magic” behind that behaviour. Now than that’s been solved, I’m trying to make my dialog box title be a variable, like this:

Dialog.setup("$testname1")

I’ve tried using <> and changing the quotations, but nothing seems to work. I don’t want to open a new question just for this, so I hope I’m not doing something wrong here.

Thanks again for the answer and for your time!

Basically, you can have a string like '..."..."...' just fine, but if you put another ' in the middle, then it stops being a string at that point, and anything after that will be treated as code. To get around that you have to “escape” the quote mark by putting a \ in front of it.

Anyways, for your current problem, instead of passing a string containing the name of the variable, you need to pass the value of the variable. Just do this:

<<run Dialog.setup($testname1)>>

That should do the trick.

Unfortunately, this forum hides the content of macros unless you mark that part of your text as “Preformatted text” (using the </> button).

Hope that helps! :slight_smile:

1 Like

You have to do it like this:

<<run Dialog.setup($testname)>> /* setup dialog box */
<<run Dialog.wiki("Hello, world!")>> /* add content to dialog box */
<<run Dialog.open()>> /* display dialog box */

Dialog.setup() doesn’t open a dialog, it only ‘prepares’ it to be opened by Dialog.open().

Unfortunately, you also can’t use Dialog.setup() and Dialog.open() if a dialog is already open. If you’re planning to use dialogs a lot in your story, I’d define a macro to handle all the dialog stuff. Put into your Story Javascript:

function dialog(title = "Default Title", message) {
    if (!Dialog.isOpen()) {
        Dialog.setup(title);
        Dialog.wiki(message);
        Dialog.open();
    } else {
        Dialog.wiki(message);
    }
}

Macro.add('dialog', {
    tags: null,
    handler: function() {
        title = this.args[0]
        message = this.payload[0].contents

        dialog(title, message)
    }
});

That defines a custom <<dialog>> macro you can use like this:

<<dialog "This is a title!">>Hello, world!<</dialog>>

<<dialog>> This text will be added onto the previous dialog!<</dialog>>

<<dialog "Invisible title!">> The title on this macro will be ignored
because the previous dialog is still open!<</dialog>>

<<run Dialog.close()>>
<<dialog "This is another title!">>
    This text is displayed in a new dialog with a new title,
    because Dialog.close() closed the previous one.
<</dialog>>

Also, you seem confused by whether or not to use quotation marks around variables. It is pretty confusing. Suppose you have code like this:

<<set $defaultName to "John Smith">>
<<set $name to "">>

<<textbox "$name" $defaultName>>

Why doesn’t $defaultName have quotes around it? Because you’re passing the content of the variable to the macro; the above is equivalent to typing <<textbox "$name" "John Smith">>.

So why does $name have quotes around it? Because without the quotation marks, Sugarcube would read the content of the $name variable, i.e., "".

The creator of Sugarcube had to work around this, so they had macros like <<textbox>> that modify variables directly require you to quote the variable name so the code knows which variable to access. In all other situations, where you want the content of the variable instead, you don’t use the quotation marks.

In this case, you want Dialog.setup($testname1) (or <<dialog $testname1>> if you’re using the macro above), since you want the content of the $testname1 variable, not the variable itself.

1 Like

Beyond everything else mentioned within the previous replies here, I want to touch on two things:

  1. Your example unnecessarily quotes the link markup being passed as an argument to <<button>>. Generally, macros that create, or accept, links will directly accept the link, and image, markup as arguments—i.e., there’s no need for quotes around the link markup at all.
  2. Your example erroneously attempts to use the setter component of the link markup being passed as an argument to <<button>>. Generally, link creating macros that are containers—i.e., have a closing tag; e.g., <<link>> and <<button>>—and execute their contents upon being activated do not support use of the setter component, since you can simply put <<set>> invocations within their contents.

Both of these are noted within the <<button>> macro’s documentation.

With those, and the previously mentioned quoting issue, in mind, the Dialog.wiki() call from your original example should look something like the following:

<<run Dialog.wiki('<<textbox "$nametest1" "" autofocus>><<button [[Done|fbtemp]]>><<run $photoArray.pushUnique("test2")>><<set $upPhoto -= 1>><<run Dialog.close()>><</button>>')>>
1 Like

Thanks a lot for all the answers and the help all around.