Hi,
I am following along the tutorial at Writing a client/server Eliom application.
I can’t compile the code because of the error :
File "graffiti.eliom", line 1, characters 12-23:
1 | open%shared Js_of_ocaml
^^^^^^^^^^^
Error: Unbound module Js_of_ocaml
make: *** [Makefile.eliom:169 : byte] Erreur 1
But if I try to opam install js_of_ocaml I get :
[NOTE] Package js_of_ocaml is already installed (current version is 5.7.0).
Setup :
Using ocaml 5.1.1.
eliom 10.3.1
Got the dependency by opam install .
, then to fix the dependencies :
opam install ocsigen-i18n pgocaml_ppx
opam install ocsigen-ppx-rpc
I probably miss something in the doc, but I don’t know how to debug it.
2 Likes
for the record I fixed it by using open%client Js_of_ocaml
Unbound module is likely a build system issue and not a package manager one. Do you have a makefile or a dune file ?
Nevermind, this is the correct fix.
Opening Js_of_ocaml
in shared mode does not make sense, because it is the module for javascript bindings, which only make sense in the client. This was a mistake in the tutorial, the maintainers are informed and this will be fixed.
Thanks lot for finding this !
1 Like
Thank you both.
Indeed this was accepted by the old build system but not by the new dune-based one.
The tutorial is fixed.
Do not hesitate to report other problems.
1 Like
Thanks for the replies.
As of other problems, in “Drawing on a canvas”, there is a part that says
Here is the (full) new version of the program:
(I put the code at the end)
The code at this point doesn’t compile, which really confused me.
What I understood is that :
It lacks
open%server Eliom_content.Html.D
to use html
.
Then there is a few value which are not yet used, which cause unused value errors.
But then
let%server main_service =
Graffiti_app.create
is also unused.
At this point I think it is unclear what to do. I first I thought we were missing the Graffiti_app.register
. At the beginning of the tuto, we do Eliom_service.create
+ Eliom_registration.Html.register
. Then we start doing Eliom_service.create
+ Graffiti_app.register
. At no point it is mentioned that Graffiti_app.create
will create and register the service in one go.
let%server _ =
Graffiti_app.create
works as expected.
Here’s the code :
(* Modules opened with open%shared are available in client and server-code *)
open%shared Eliom_content
open%client Js_of_ocaml
open%client Js_of_ocaml_lwt
module%server Graffiti_app =
Eliom_registration.App (
struct
let application_name = "graffiti"
let global_data_path = None
end)
let%shared width = 700
let%shared height = 400
let%client draw ctx ((r, g, b), size, (x1, y1), (x2, y2)) =
let color = CSS.Color.string_of_t (CSS.Color.rgb r g b) in
ctx##.strokeStyle := (Js.string color);
ctx##.lineWidth := float size;
ctx##beginPath;
ctx##(moveTo (float x1) (float y1));
ctx##(lineTo (float x2) (float y2));
ctx##stroke
let%server canvas_elt =
Html.D.canvas ~a:[Html.D.a_width width; Html.D.a_height height]
[Html.D.txt "your browser doesn't support canvas"]
let%server page () =
html
(head (title (txt "Graffiti")) [])
(body [h1 [txt "Graffiti"];
canvas_elt])
let%client init_client () =
let canvas = Eliom_content.Html.To_dom.of_canvas ~%canvas_elt in
let ctx = canvas##(getContext (Dom_html._2d_)) in
ctx##.lineCap := Js.string "round";
draw ctx ((0, 0, 0), 12, (10, 10), (200, 100))
let%server main_service =
Graffiti_app.create
~path:(Eliom_service.Path [""])
~meth:(Eliom_service.Get Eliom_parameter.unit)
(fun () () ->
(* Cf. section "Client side side-effects on the server" *)
let _ = [%client (init_client () : unit) ] in
Lwt.return (page ()))
1 Like
Thank you very much for the report!
The Graffiti tutorial has been updated. It should be much better now.
It was not working well with the new build system.
Do not hesitate to report other problems.
1 Like
I did the whole tutorial in one go with the new version, didn’t found problems.
I don’t need it, but when clicking one the “switch to Reason syntax button”, there is some
(* Error while translating to Reason *)
Thanks for the quick replies, and for fixing the tutorial. Seing it in action this framework is even more interesting than I thought.
1 Like
Thank you!
Indeed we are using the OCaml to Reason converter provided by Reason but it fails on some examples. May be we could remove the conversion feature. I’m not even sure it is up to date. I’m wondering whether some people are still using the Reason syntax.