Search code examples
f#elm

Why does Cmd.OfAsync.perform expect 'unit -> 'a' instead of expect 'Message'?


As far as I understand Cmd.OfAsyn.perform has three inputs:

Cmd.OfAsync.perform
    asyncFunction   // The async function to perform
    input           // Input to the async function
    successMessage  // Message to dispatch on success

The success message should refer to another message which then eventually results to Cmd.none.

In my example I want to download a file from the browser but I receive the error:

This expression was expected to have 'unit -> 'a' but here has type 'Message'

My code is:

| DownloadFile ->
    let downloadCmd =
        Cmd.OfAsync.perform
            (fun _ -> async { Browser.Dom.window.location.href <- "/api/file/download"} )
            ()
            // The below line throws the error.
            FileDownloaded
    { model with IsDownloading = true }, downloadCmd
| FileDownloaded ->
    { model with IsDownloading = false }, Cmd.none

I don't understand why FileDownloaded is expected to have type unit'. Where is my mistake?


Solution

  • I don't understand why FileDownloaded is expected to have type unit. Where is my mistake?

    It's actually unit -> 'a (in this case 'a is the Message type, see source). The last argument to Cmd.OfAsync.perform is a function that returns a message, not the message itself.

    To fix, change:

    FileDownloaded
    

    to:

    (fun () -> FileDownloaded)