Tuples in ports

Hello there,

I just fiddled around with ports and I wanted to send 2 values ( as tuple ). the Elm code copiles just fine but when I’m running the app I get this error:

Uncaught Error: Trying to send an unexpected type of value through port `storageData`:
[object Object]

this is my port / subscription / message-type in elm:

port storageData : (( String, Maybe String ) -> msg) -> Sub msg


subscriptions : Model -> Sub Msg
subscriptions _ =
    storageData StorageData


type Msg
    = StorageData ( String, Maybe String )

and thats the relevant part in js:

app.ports.storageRead.subscribe(function(key){
    app.ports.storageData.send(key, storage.getItem(key));
});

I also tried to put the 2 parameters in js in another pair of brackets so that they arent 2 parameters but 1 tuple ( I guess ) but didnt change anything

this javascript

app.ports.storageData.send([ key, storage.getItem(key) ] );

worked for this elm port

port storageData : (( String, Maybe String ) -> msg) -> Sub msg

ps: hadn’t been too adventurous with port types myself and I learnt something today :grinning:

2 Likes

Ports are unfortunately one place where Elm’s error messages often leave something to be desired.

Javascript doesn’t have tuples. You must instead use a two-element array (which corresponds to a tuple on Elm’s side).

EDIT: Ah it appears I was beaten to the punch.

2 Likes

It is worth noting as well that you can always just take a Json.Value and decode it any way you like, or encode one and pass it in (as appropriate for the port direction). This is useful when you want to get differently shaped data as a custom type, for example.

2 Likes

Here’s the section of the guide that lists what various JS values get turned into Elm values. It’s under the section on flags but it holds true for ports too.

2 Likes