Set Snap! variable's value to a list/array value

Hello,

I am using Snap!'s API (https://github.com/jmoenig/Snap/blob/master/API.md) to set a variable's value with JavaScript. However, when I set the value to an array value, the variable in Snap! shows a string value:string
How would I set the value to an array value?

Thanks.

run(JS(IDE_Morph.prototype.setVar('current song',new List(['Note','Length']))))

that's right. As @18001767679 has correctly pointed out Snap's data type isn't an array but a list, but you can easily turn a JS array into a Snap-List by calling the constructor and passing in an array

new List(array)

so, to make a list of numbers you could write:

new List([60, 64, 67])

or, to make a song as a table of notes with duration values you could do something like this:

new  List([
    new List([60, 1]),
    new List([64, 1]),
    new List([67, 2])
])

For non-Snap! objects (i.e. not Sprites, Lists, Costumes, Sounds), the toString() method is invoked for displaying; the actual value is the object.

@18001767679
@jens
@snapenilk

Thanks for the help. Unfortunately, when I try to use, "new List," I get the, "'List' is not defined," error, but that may be an error with my setup. I tried importing the List library from https://www.collectionsjs.com/list, but now the Snap! variable appears as [object Object]. Could you point me in the right direction of the List library that Snap! expects?

Hi Eric, I was talking about Snap's own data structure, which is in Snap's source code, the file named list.js. I guess I'm puzzled about your setup. By the time you're communicating with Snap over the api you must already have access to Snap's source code and to the List constructor, so you shouldn't have to import any external library for this...

Got it. I was able to import the List class from the Snap! source code, but when running this code:

new List(["Hello", "There"])

I got output similar to this:

image

Is there a way I could make this look more like the way Snap! displays arrays? Thanks.

Looks like there's a namespace conflict in your JS constructors and the Snap! List data structure got overloaded by another one with the same name... could that be the problem?

@jens

I don't think that's the problem, since this is what I get when console.logging List immediately before using it:
List

And the message in the screenshot above matches the source code in lists.js (https://github.com/jmoenig/Snap/blob/master/src/lists.js):
list in lists

It makes sense that I get the output I receive in the variable given @snapenilk's comment, since the toString method is called on the List object I attempt to set the variable's value to.

Am I supposed to use a different List class other than the one defined in lists.js?

Can you show me your code? Mine works:

mine works too

Kids, please don't spam threads.

okie

@jens
@18001767679

Mine works within Snap! as well (on my site):

works 1
works 2

But not from the JavaScript of my site:
no work 1

no work 2
(where this.snapIde is taken from contentWindow.world.children[0] and List is taken from lists.js)

If you would like to see more of my code, I could send it to you, but I believe the output makes sense given the toString function noted earlier. Also, if all else fails, I could always construct the Snap! lists on the Snap! side after receiving a csv string, but I would prefer to do so on the JavaScript side. Thanks again!

Hi @ericstein, did you find out what may be behind this issue? Do you think it's that compound user-defined data can't be shared across namespaces? Otherwise I can try to dig into this and perhaps append the Snap-API with methods that let you create and interact with Snap lists remotely...

[edit:] Oh, of course the issue could be a same-origin-policy browser-bureaucratic one...

[later still: ] Okay, I've set up a little iFrame for Snap myself and added lists.js to the page that contains the iFrame, and then I can set variables to Snap lists without any problem. So, there doesn't seem to be any problem related to passing Snap data types in and out of an iFrame in principle.

[and another edit:] After some more experiments I've decided to simply add a newList() function to the API, so you no longer have to load the lists.js file into your embedding page at all. Hope this helps! I've also updated the API documentation for this. Please let me know if something remains unclear or doesn't work the way you think it should. Thanks!

@jens

That's great news! I'll pull in the latest API and let you know how it goes. Thanks!

I believe the reason for it working in your case and not in mine was the fact that my iFrame loaded a locally-running instance of Snap!, not Snap! directly from https://snap.berkeley.edu/. Whichever the case, your addition to the API will likely solve the issue.

Sorry for the spam, but I just wanted to confirm that the new function did indeed solve the issue. Thanks again!

Glad to hear, thanks!