Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

Passing arguments in Electron ipcRenderer/ipcMain #76

Open
dough654 opened this issue Jan 29, 2019 · 3 comments
Open

Passing arguments in Electron ipcRenderer/ipcMain #76

dough654 opened this issue Jan 29, 2019 · 3 comments

Comments

@dough654
Copy link

I apologize if the solution to my issue is simple, as I'm still learning Fable (and F# actually).

I'm trying to use the Electron ipcRenderer and ipcMain for inter/process communication (like I normally would in regular electron development). In my renderer I have something like this:

electron.ipcRenderer.send("Hello", ["World"])

Then in my Main.fs, I set up a listener:

electron.ipcMain.on("Hello", unbox(fun x -> printfn "Hello %A" x)) |> ignore

And when I execute, I get the text Hello [object Object] (which I recognize very well from Javascript development.)

The type signature of of the 'send' function is (channel: string *, args: obj []) -> unit

So if i'm reading that correctly, the send function requires a string to representing the channel name, and arguments which is a list of Objects?

So my question is, how can I enforce a type when sending arguments through ipcRenderer send and receive that same type in my callback function in ipcMain?

Also, is there any documentation for these import APIs? I was not able to find any.

@MangelMaxime
Copy link
Member

I don't think you can enforce the type of the sent arguments and retrieved arguments.

The reason, being sometimes your send function will want to send string, another time int, or MyCustomType. This is why it's mapped to obj so you can pass any type to it.

About the [object Object], if I would be in this situation I would try to print x using JS.console.log(x) which doesn't try to format as printfn do and you will be able to see what you received in response.

From there, you will either be able to use x and retrieve the value or identify a problem in the binding.

@dough654
Copy link
Author

@MangelMaxime Thanks for the suggestion. I'll give it a try. Seems like some type binding would have to take place at some point in order to use x in any meaningful way on the ipcMain side of things. I'll try the JS.Console.log and see if I get any insights from that.

@MangelMaxime
Copy link
Member

A solution to give some type information would be to have something like:

type IpcRenderer =
    abstract send<'T> : channel: string * args: 'T [] -> unit
    abstract on<'T> : channel: string * ('T [] -> unit) -> unit

let ipcRenderer = Unchecked.defaultof<IpcRenderer>

ipcRenderer.send<int>("channel1", [| 1; 2; 3 |])

ipcRenderer.on<int>("channel1", (fun x -> ()))

But the 'T type from send and on are not related to the type system information. It would still be the job of the developer to be sure to set 'T to the same type for the same channel. We can't make a strong relationship between send<'T> and on<'T> because depending on the channel the argument type will not be the same.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants