Warning: Reason support is experimental. We are looking for beta-tester and contributors.

How to send a file to the server without stopping the client process?

This requires Eliom ≥ 3.1.

Due to security reasons, browsers have limitations on sending files. But if the file is chosen by the user through an input file element, there is a way to send it to the server. You can't use the server_function or let%rpc syntax for this, but you can use Eliom.Client.call_caml_service.

Example:

[%%client
open Js_of_ocaml
open Js_of_ocaml_lwt
open Eliom.Content.Html
open Eliom.Content.Html.F]

let pic_service =
  Eliom.Service.create_ocaml ~name:"upload_pic" ~path:Eliom.Service.No_path
    ~meth:(Eliom.Service.Post (Eliom.Parameter.unit, Eliom.Parameter.file "f"))
    ()

let () =
  Eliom.Registration.Ocaml.register ~service:pic_service (fun _ _ ->
      (* get the file ... *)
      Lwt.return_unit)

let%client upload_pic_form () =
  let file = D.Raw.input ~a:[a_input_type `File] () in
  let submit_elt = D.Raw.input ~a:[a_input_type `Submit; a_value "Send"] () in
  (let open Lwt_js_events in
  async (fun () ->
      clicks (To_dom.of_input submit_elt) (fun _ _ ->
          Js.Optdef.case
            (To_dom.of_input file)##.files
            Lwt.return
            (fun files ->
              Js.Opt.case
                files ## (item 0)
                Lwt.return
                (fun file ->
                  Eliom.Client.call_ocaml_service ~service:~%pic_service ()
                    file)))));
  [txt "Upload a picture:"; file; submit_elt]