Skip to content

Instantly share code, notes, and snippets.

@Kimserey
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kimserey/f513961cb01e67b9964b to your computer and use it in GitHub Desktop.
Save Kimserey/f513961cb01e67b9964b to your computer and use it in GitHub Desktop.
Snippet Websharper - UI.Next using Ajax call to test REST API
namespace UINextAjax
open System
open WebSharper
open WebSharper.JavaScript
open WebSharper.JQuery
open WebSharper.UI.Next
open WebSharper.UI.Next.Client
[<JavaScript>]
module Client =
open WebSharper.UI.Next.Html
type Post =
{ userId: int
id: int
title: string
body: string }
let ( <*> ) f x = View.Apply f x
let Ajax m url : Async<string> =
Async.FromContinuations <| fun (ok, ko, _) ->
JQuery.Ajax(
JQuery.AjaxSettings(
Url = "http://jsonplaceholder.typicode.com" + url,
Type = m,
ContentType = "application/json",
DataType = JQuery.DataType.Text,
Success = (fun (result, _, _) -> ok (result :?> string)),
Error = (fun (jqXHR, _, _) -> ko (System.Exception(jqXHR.ResponseText)))))
|> ignore
let private getPosts () : Post list Async =
async { let! response = Ajax RequestType.GET "/posts"
return Json.Deserialize<Post list> response }
let private posts: ListModel<int, Post> =
ListModel.Create (fun p -> p.id) []
let private comment post =
posts.Add(post)
let Main =
async {
let! postsRes = getPosts()
postsRes |> List.iter (fun p -> posts.Add p)
} |> Async.Start
let rvTitle = Var.Create ""
let rvBody = Var.Create ""
let rvShowBody = Var.Create false
let titleInput = Doc.Input [attr.placeholder "Title"] rvTitle
let bodyInput = Doc.InputArea [attr.placeholder "Body"] rvBody
let buttonInput =
View.Map2
<| fun t b -> String.IsNullOrEmpty t || String.IsNullOrEmpty b
<| rvTitle.View
<| rvBody.View
|> View.Map (fun b -> Doc.Button "Post"
<| [if b then yield attr.disabled "" ]
<| fun () -> posts.Add({title=rvTitle.Value;body=rvBody.Value;id=12;userId=1}))
|> Doc.EmbedView
let form = Doc.Concat [ h4 [text "Add new"]
div [ titleInput ]
div [ bodyInput ]
buttonInput
div [ labelAttr [ attr.``for`` "checkboxShowBody" ] [ text "Show body" ]
Doc.CheckBox [ attr.id "checkboxShowBody" ] rvShowBody ] ]
//formatting with map2
let doc =
posts
|> ListModel.View
|> View.Map2 (fun showBody ps ->
ps
|> List.ofSeq
|> List.map (fun p -> [ yield (div [ text ("Title: " + p.title) ] :> Doc)
if showBody then yield (div [ text ("Desc: " + p.body) ] :> Doc)
yield (br [] :> Doc) ] |> Doc.Concat)
|> Doc.Concat) rvShowBody.View
|> Doc.EmbedView
//formatting with apply
let doc' =
View.Const (fun showBody ps ->
ps
|> List.ofSeq
|> List.map (fun p -> [ yield (div [ text ("Title: " + p.title) ] :> Doc)
if showBody then yield (div [ text ("Desc: " + p.body) ] :> Doc)
yield (br [] :> Doc) ] |> Doc.Concat)
|> Doc.Concat)
<*> rvShowBody.View
<*> ListModel.View posts
|> Doc.EmbedView
Doc.RunById "main" <| Doc.Concat [form; doc']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment