Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Problem with accessing state.history.variables

edited June 2014 in Help! with 1.x
Hello,

I hesitate to post about this since I've seen this asked and answered elsewhere, but for some reason despite all the answers on the topic I can't seem to get it to work. I'm using SugarCube (the latest version)

What I'm trying to do is access a variable I set in twine with <<set $test = "testing">> from javascript.

To do that, I've been using: var testing = state.history[0].variables[test];

Now as I understand it, that should access the value of the $test variable and save it in testing. After I run it, however, the value of the testing variable is 'undefined'.

I'd really appreciate any assistance since I'm really banging my head against this trying to figure out where I've gone wrong.

Here is the test passage I am using:
<<silently>>
<<set $test = "test">>
<<endsilently>>
<<script>>
var testing = state.history[0].variables[test];
alert(testing);
<</script>>
I've tried using: var testing = state.history[0].variables["test"]; also with no luck.

I've also tried to do it several other ways, such as creating a macro  that takes a $value parameter and saves it in a javascript variable and alerts the value of the variable, it still comes out as undefined. I also tried putting the javascript in a story passage called PassageDone which runs the script after each passage loads. It still prints undefined.

Comments

  • Ah well never mind. I've been working on this for hours, but about a minute after I post I found the answer.

    I'll post it here in case anyone else needs help.

    Basically SugarCube has heavily modified the state.history variable. Instead of state.history[0].variables you need to write:

    state.active.variables
  • It's in the documentation (specifically: Story APIs docs > History prototype & API) that no one bothers to read.
  • For the record, I find SugarCube's documentation invaluable; I use it constantly. I wish that the other tools and headers in the Twine ecosystem were as well documented.
  • And can I reach widget's arguments with state.active.variables?

    Update: I've found some solution here, but when I use it, it doesn't work for me somehow...
    <<widget "test">>\
    <<run $(document).click(function(){
    var args = state.active.variables.args;
    $(".content").append(args.length);
    });
    >>\
    <</widget>>
    And in passage:
    <<test "testing">>
    It keeps telling me that it "cannot read property 'length' of undefined".
  • cheshire wrote:

    And can I reach widget's arguments with state.active.variables?


    As long as you're within the widget's scope, yes.  That said, you only need to do so within any &lt;&lt;script&gt;&gt; macros contained by the widget (since it doesn't process Twine $variables or operators).


    cheshire wrote:

    Update: I've found some solution here, but when I use it, it doesn't work for me somehow...

    <<widget "test">>\
    <<run $(document).click(function(){
    var args = state.active.variables.args;
    $(".content").append(args.length);
    });
    >>\
    <</widget>>
    And in passage:
    <<test "testing">>
    It keeps telling me that it "cannot read property 'length' of undefined".


    You're attempting to access data which no longer exists by the time the callback is executed (i.e. the callback you create inside the widget isn't part of the widget's scope).  You need to close over the value of $args to preserve it for the callback, this is what's known as a closure.

    Fortuitously, both &lt;&lt;run&gt;&gt; and &lt;&lt;script&gt;&gt; evaluate their contents within an anonymous function scope, so all that needs be done is to create a local reference to the value.  For example, try this:

    <<widget "test">>\
    <<run
    var args = $args;
    $(document).click(function () {
    $(".content").append(args.length);
    });
    >>\
    <</widget>>
    You could also use state.active.variables.args in place of $args in the above, but the only reason to use &lt;&lt;run&gt;&gt; instead of &lt;&lt;script&gt;&gt; is to get Twine $variable and operator processing, so that would kind of defeat the purpose of using &lt;&lt;run&gt;&gt; here.
  • Now I get it. Thanks a lot for your help.
Sign In or Register to comment.