The standard UI.Next Client-Server Application template shows you how to call the server and embed the view of the response into markup. A more low-level approach that exposes a reactive variable as well would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
open WebSharper
open WebSharper.JavaScript
open WebSharper.UI.Next
open WebSharper.UI.Next.Client
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Notation

[<JavaScript>]
module Client =

    let Main () =
        let input = Var.Create ""
        let output = Var.Create ""
        div [
            Doc.Input [] input
            Doc.Button "Send" [] (fun () ->
                async {
                    let! res = Server.DoSomething input.Value
                    output := res
                }
                |> Async.Start
            )
            hr []
            h4Attr [attr.``class`` "text-muted"] [text "The server responded:"]
            divAttr [attr.``class`` "jumbotron"] [h1 [textView output.View]]
        ]
By on 11/23/2015 10:13 AM ()

Hi, Adam.

I'm afraid you misunderstood me. My main problem was to call the remote part periodically, not the calling and displaying the result itself.

It seems I've found a solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[<JavaScript>]
module Client =
    open System
    open WebSharper.JavaScript

    let main () =
        let rvInput = Var.Create ""
        let vFibResult = Var.Create 0
        let rnd = Random()

        let _h = // <=== what about this handle? Should I free it at some time? Can it cause a leak?
            JS.SetInterval (fun () ->
                async {
                    let n = rnd.Next(20, 39)
                    rvInput.Value <- string n
                    let! res = Server.calculateFib n
                    vFibResult.Value <- res
                } |> Async.Start) // <=== is it ok to spawn a new Async every second?
                1000

        div [
            h1 [text "N = "; textView rvInput.View]
            hr []
            h3Attr [attr.``class`` "text-muted"] [text "The server responded:"]
            divAttr [attr.``class`` "jumbotron"] 
                    [h1 [text "Fib = "; textView (vFibResult.View |> View.Map string)]]
        ]

The only thing I'm warried about now is spawning Asyncs, number of which can uncontrollably grow. Could you please elaborate on how Asyncs actually works at runtime on both client and server sides?

By on 11/23/2015 11:05 AM ()

You can read about asyncronous calls here.

By on 11/23/2015 12:58 PM ()

Thanks. Do recursive async fucntions work ok? I mean something like this:

1
2
3
4
5
6
let rec loop() = 
	async {
    	...
        return! loop()
    }
Async.Start (loop())

I'm asking because the documenation says

The implementation uses nested JavaScript callbacks.

Do those callbacks stack on each other, causing memory leak? In F# that function is TCO, so no problem.

By on 11/23/2015 11:46 PM ()

OK, I've changed it to use an infinite loop:

1
2
3
4
5
6
7
8
9
async {
    while true do
        let n = rnd.Next(20, 39)
        rvInput.Value <- Some n
        let! res = Server.calculateFib n
        vFibResult.Value <- Some res
        vNow.Value <- DateTime.Now
        do! Async.Sleep 1000
    } |> Async.Start

It feels much more reliable and predictable.

By on 11/23/2015 12:17 PM ()

It should be read "What is the recommended way to call remote code (marked with the Rpc attribute) from client (JS) code and update a Var with results?

By on 11/23/2015 9:14 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper