Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing multiple arguments to Javascript via port

Tags:

elm

I need to pass a few parameters to Javascript, but for a strange reason it does not compile. I started with:

port check : String -> Cmd msg

this works fine (as taken directly from JavaScript Interop). But when I am adding another parameter

port check : Int -> String -> Cmd msg

I am getting

1| port check : Int -> String -> Cmd msg
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You are saying it should be:

Int -> String -> Platform.Cmd.Cmd msg

But you need to use the particular format described here: http://guide.elm-lang.org/effect_managers/

I solved this simply by reducing arguments back to one

type alias Bundle = (Int, String)
port check : Bundle -> Cmd msg

but that would be cleaner if I could simply do

app.ports.check.subscribe(function(arg1, arg2) {
});

Why it doesn't compile?

like image 771
Lukasz Guminski Avatar asked Aug 28 '16 09:08

Lukasz Guminski


People also ask

How to pass multiple arguments in JavaScript function?

When you call a function in JavaScript, you can pass in any number of arguments, regardless of what the function declaration specifies. There is no function parameter limit. In the above function, if we pass any number of arguments, the result is always the same because it will take the first two parameters only.

How to pass multiple arguments in a function?

The * symbol is used to pass a variable number of arguments to a function. Typically, this syntax is used to avoid the code failing when we don't know how many arguments will be sent to the function.

Can a method accept more than one argument?

Multiple ArgumentsYou can actually have your variable arguments along with other arguments. That is, you can pass your method a double, an int, and then a String using varargs.


2 Answers

ports can only have one parameter. If you need to pass multiple parameters then your only options are to pass a tuple (like you did with Bundle) or a record.

On the js side, you'll have to take one parameter but you can destructure it after with whatever var names you want

app.ports.check.subscribe(function(arg) {
  var [arg1, arg2] = arg;
});

If you're using ES6, then you do have some nicer options for destructuring in the function params if you use a record like this:

app.ports.check.subscribe(function({arg1: arg1, arg2: arg2}) {
});
like image 190
robertjlooby Avatar answered Oct 21 '22 22:10

robertjlooby


I noticed you don't really have to "decode" much on the Javascript side. So, you can package your single parameter up as a nice type in ELM.

Do something like this in your elm:

type alias MyObject = 
  { name: String 
  , displayDate: String
  , subTitle: String
  , hashTag: String
  }

port check : MyObject -> Cmd msg 

Then in the javascript you can just do this:

app.ports.check.subscribe(function(myObject) {
            alert( myObject.name);
            alert( myObject.displayDate);
            alert( myObject.subTitle);
            alert( myObject.hashTag);
        });
like image 25
user7106980 Avatar answered Oct 21 '22 22:10

user7106980