Howdy, Stranger!

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

[twine 2 & sugarcube 2] Is it possible to pass an array of objects to a widget?

Hello there forum, I've been searching a while for an answer to the question: can I pass an array of objects to a widget?
To be clear, I mean passing an array variable to a widget, as in
/* define an array of people (objects) with names */
<<set $arr to [{name:'alice'}, {name:'bob'}, {name:'casey'}]>>
$arr[0].name
/* Outputs "alice" */

/* do something to the array */
<<arraywidget $arr>>

/* let's say the widget looks like */
<<widget "arraywidget">>
  <<for _i = 0; _i < $args.length; _i++>>
    <<print $args[_i].name>>
  <</for>>
<</widget>>

The above widget definition prints nothing. I tried to fix it by reading to a temporary variable first:
<<widget "wordywidget">>
  <<for _i = 0; _i < $args.length; _i++>>
    <<set _person to $args[_i]>>
    <<print _person.name>>
  <</for>>
<</widget>>

Which still prints nothing. During testing I accidentally left out the ".name" in the first widget and got
<<widget "borkedwidget">>
  <<for _i = 0; _i < $args.length; _i++>>
    <<print $args[_i]>>
  <</for>>
<</widget>>
which outputs "[object Object], [object Object], [object Object]", i.e. the entire array as one element of $args. (Since I didn't explicitly print the commas, I'm pretty sure this is the string representation of the outer array $arr.)

Is there any way to make this work? Currently I only know of one workaround: saving the array to a global variable used by the widget. I would much prefer passing the array as an argument though, passing through globals gives me nightmares of assembly coding.

Any tips or fixes would be greatly appreciated!

Comments

  • As noted within the <<widget>> macro's documentation, its internal $args variable is an array, since you may pass multiple arguments to the widget.

    In your first example, you are incorrectly attempting to reference it as though it was the array you passed in. You needed to index its zeroth position, which yields the array you passed in, and then iterate over that. For example:
    <<widget "arraywidget">>\
    <<if $args.length gt 0>>\
    	<<set _passedArr to $args[0]>>\
    	<<for _i to 0; _i lt _passedArr.length; _i++>>
    		<<print _passedArr[_i].name>>
    	<</for>>
    <</if>>\
    <</widget>>
    
  • You needed to index its zeroth position, which yields the array you passed in, and then iterate over that.

    You know, I could have sworn I tried that already, but I must have mucked it up that time. Anyway, your snippet works just fine, so thank you kindly for the clarification!
  • Nice, I guess it's done in a similar way as in C.
Sign In or Register to comment.