The error message says "I don't know how to translate your call to access Remoter.rndData, a server-side value." Indeed, it's recommended to make this a function: crossing the client-server boundary should always be via function calls.

So that's your issue #1. The next issue is that you are trying to compute a Base.DataTable value on the server, which you can't. This type represents the appropriate client-side type from Google Visualization, you can only use it in client-side contexts. In other words, .NET knows nothing about addColumns, addRows, etc. on the server - since those are implemented in JavaScript.

The solution is to compute data in a compatible way on the server, convert it to the desired representation on the client, and use it there as such.

On the server:

1
2
3
4
5
[<Rpc>]
let GetRndData () = 
    let rnd = new Random()
    let rr = Array.init 4 (fun _ -> rnd.NextDouble())
    rr

On the client:

1
2
3
4
5
6
7
8
9
10
11
[<JavaScript>]
let dt =
    let rr = Remoter.GetRndData ()
    let data = new Base.DataTable()        
    data.addColumn(ColumnType.NumberType, "Random Number") |> ignore
    data.addRows(4) |> ignore
    data.setValue(0,0,rr.[0])
    data.setValue(1,0,rr.[1])
    data.setValue(2,0,rr.[2])
    data.setValue(3,0,rr.[3])
    data
By on 12/24/2014 2:50 AM ()

Hi Adam, Thank you for your reply. I arrived at a different solution which works, but according to what you said in your reply, I don't understand why

On the server:

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
[<Rpc>]
let rndData num = 
    let rnd = new Random()
    Array.init num (fun _ -> rnd.NextDouble())

[<JavaScript>]
let OtherData() =
    let rr = rndData 8                
    let data = new Base.DataTable()
    data.addColumn(ColumnType.StringType, "Year") |> ignore
    data.addColumn(ColumnType.NumberType, "Sales") |> ignore
    data.addColumn(ColumnType.NumberType, "Expenses") |> ignore
    data.addRows(4) |> ignore
    data.setValue(0, 0, "2004")
    data.setValue(0, 1, rr.[0])
    data.setValue(0, 2, rr.[1])
    data.setValue(1, 0, "2005")
    data.setValue(1, 1, rr.[2])
    data.setValue(1, 2, rr.[3])
    data.setValue(2, 0, "2006")
    data.setValue(2, 1, rr.[4])
    data.setValue(2, 2, rr.[5])
    data.setValue(3, 0, "2007")
    data.setValue(3, 1, rr.[6])
    data.setValue(3, 2, rr.[7])
    data

On the client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[<JavaScript>]
let dt = Remoter.OtherData()

[<JavaScript>]
let Main() =
    Div[]
    |>! OnAfterRender (fun container ->
        let viz = new LineChart(container.Body)
        viz.draw(dt, 
            LineChartOptions(
                width = 400,
                height = 240,
                legend = Legend(position = LegendPosition.Top),
                title = "Company Performance")))

According to what you said then, this shouldn't work because I am generating the data table on the server-side. Does it work because I attributed OtherData() as <JavaScript> even though it was on the server-side? Is this bad practice?

Thanks for your time!

By on 12/24/2014 4:00 AM ()

Your OtherData function is not on the server, it is running on the client side - as directed by the [<JavaScript>] attribute. Functions are "assigned" to tiers based solely on their annotations/attributes, you could even put everything in a single file as long as each function is marked properly.

Hope this helps.

By on 12/24/2014 3:11 PM ()
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