Alright, I managed to do it in the end. Here's how I did it basically.

I created an extra input and made it's stream available.

1
2
3
let feedback, feedbackStream =
    Piglet.Yield ""
    |> fun feedback -> feedback, feedback.Stream

With the stream now available, within the Piglet.run I could do something like this

1
2
3
Start (fun () -> Remoting.Call data) (fun result ->
    feedbackStream.Trigger (Result.Success result)
)

Within the render function, I did something like this

1
Div [] |> Controls.ShowString feedback (fun x -> string x)

I don't know if this is the most optimal way but it's working for me so far.

By on 3/7/2015 12:20 PM ()

What you probably want to look at here is the Piglet.MapAsync family of functions, and more precisely Piglet.MapToAsyncResult. For example, if you have a RemoteFunction that returns an Async<option<string>> (None on success, Some "error message" otherwise) then you can do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
yourPiglet
|> Piglet.MapToAsyncResult (fun x ->
    async {
        let! result = RemoteFunction x
        return
        	match result with
            | None -> Result.Success x
            | Some message -> Result.Failwith message
    }
)
|> Piglet.TransmitReader
|> Piglet.Render (fun yourPigletStreams result ->
    Div [
        // Render your piglet...
        Div [] |> Controls.ShowErrors result (fun messages ->
            Seq.map Text messages)
    ]
)

Notice also the use of Piglet.TransmitReader to pass the final value as a read-only stream to the render function. This is more composable that extracting the stream explicitly like you did.

By on 3/8/2015 3:26 AM ()

Indeed, that looks very clean. I will refactor my code around that. Thank you very much.

By on 3/8/2015 9:35 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