Delete album action

Note that the code from previous section allows us to navigate to to /admin/delete/%d, but we still are not able to actually delete an album. That's because there's no handler in our app to delete the album from database. For the moment both GET and POST requests will do the same, which is return HTML page asking whether to delete the album.

In order to implement the deletion, add deleteAlbum to Db module:

Db.fs

  57: 
  58: 
  59: 
let deleteAlbum (album : Album) (ctx : DbContext) = album.Delete() ctx.SubmitUpdates()

The snippet takes an Album as a parameter - instance of this type comes from database, and we can invoke Delete() member on it - SQLProvider keeps track of such changes, and upon ctx.SubmitUpdates() executes necessary SQL commands. This is somewhat similar to the "Active Record" concept.

Now, in App module we can distinguish between GET and POST requests:

App.fs

  43: 
  44: 
  45: 
  46: 
  47: 
  48: 
  49: 
  50: 
  51: 
  52: 
  53: 
  54: 
  55: 
let deleteAlbum id = let ctx = Db.getContext() match Db.getAlbum id ctx with | Some album -> choose [ GET >=> warbler (fun _ -> html (View.deleteAlbum album.Title)) POST >=> warbler (fun _ -> Db.deleteAlbum album ctx; Redirection.FOUND Path.Admin.manage) ] | None -> never
  • deleteAlbum WebPart delegates the request to choose with two possible WebParts (GET or POST requests).
  • GET and POST are WebParts that succeed (return Some x) only if the incoming HTTP request is of GET or POST verb respectively.
  • after successful deletion of album, the POST case redirects us to the Path.Admin.manage page

Important: We have to wrap both GET and POST handlers with a warbler - otherwise they would be evaluated just after Some album match, resulting in invoking e.g. Db.deleteAlbum even if POST does not apply.

The grid can now contain a column with link to delete the album in question:

View.fs

  64: 
  65: 
  66: 
  67: 
  68: 
  69: 
  70: 
  71: 
  72: 
  73: 
  74: 
  75: 
  76: 
  77: 
  78: 
  79: 
  80: 
  81: 
  82: 
  83: 
  84: 
let manage (albums : Db.AlbumDetails list) = [ h2 "Index" table [ yield tr [ for t in ["Artist";"Title";"Genre";"Price";"Action"] -> th [ Text t ] ] for album in albums -> tr [ for t in [ truncate 25 album.Artist truncate 25 album.Title album.Genre album.Price.ToString("0.##") ] -> td [ Text t ] yield td [ a (sprintf Path.Admin.deleteAlbum album.Albumid) [] [Text "Delete"] ] ] ] ]
  • there's a new "Action" column header in the first row
  • in the last column of each album row comes a cell with link to delete the album
  • note, we had to use the yield keyword again
    Multiple items
    namespace FSharp

    --------------------
    namespace Microsoft.FSharp
    Multiple items
    namespace FSharp.Data

    --------------------
    namespace Microsoft.FSharp.Data
    namespace FSharp.Data.Sql
    Multiple items
    type LiteralAttribute =
    inherit Attribute
    new : unit -> LiteralAttribute

    Full name: Microsoft.FSharp.Core.LiteralAttribute

    --------------------
    new : unit -> LiteralAttribute
    val ConnectionString : string

    Full name: SuaveMusicStore.Db.ConnectionString
    type Sql = SqlDataProvider<...>

    Full name: SuaveMusicStore.Db.Sql
    type SqlDataProvider

    Full name: FSharp.Data.Sql.SqlDataProvider


    <summary>Typed representation of a database</summary>
    <param name='ConnectionString'>The connection string for the SQL database</param>
    <param name='ConnectionStringName'>The connection string name to select from a configuration file</param>
    <param name='DatabaseVendor'> The target database vendor</param>
    <param name='IndividualsAmount'>The amount of sample entities to project into the type system for each SQL entity type. Default 1000.</param>
    <param name='UseOptionTypes'>If true, F# option types will be used in place of nullable database columns. If false, you will always receive the default value of the column's type even if it is null in the database.</param>
    <param name='ResolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types.</param>
    <param name='Owner'>The owner of the schema for this provider to resolve (Oracle Only)</param>
    <param name='CaseSensitivityChange'>Should we do ToUpper or ToLower when generating table names?</param>
    <param name='TableNames'>Comma separated table names list to limit a number of tables in big instances. The names can have '%' sign to handle it as in the 'LIKE' query (Oracle and MSSQL Only)</param>
    <param name='OdbcQuote'>Odbc quote characters: Quote characters for the table and column names: `alias`, [alias]</param>
    <param name='SQLiteLibrary'>Use System.Data.SQLite or Mono.Data.SQLite or select automatically (SQLite only)</param>
    namespace FSharp.Data.Sql.Common
    type DatabaseProviderTypes =
    | MSSQLSERVER = 0
    | SQLITE = 1
    | POSTGRESQL = 2
    | MYSQL = 3
    | ORACLE = 4
    | MSACCESS = 5
    | ODBC = 6
    | FIREBIRD = 7

    Full name: FSharp.Data.Sql.Common.DatabaseProviderTypes
    Common.DatabaseProviderTypes.POSTGRESQL: Common.DatabaseProviderTypes = 2
    type CaseSensitivityChange =
    | ORIGINAL = 0
    | TOUPPER = 1
    | TOLOWER = 2

    Full name: FSharp.Data.Sql.Common.CaseSensitivityChange
    Common.CaseSensitivityChange.ORIGINAL: Common.CaseSensitivityChange = 0
    type DbContext = SqlDataProvider<...>.dataContext

    Full name: SuaveMusicStore.Db.DbContext
    type dataContext =
    member ClearUpdates : unit -> List<SqlEntity>
    member CreateConnection : unit -> IDbConnection
    member GetUpdates : unit -> List<SqlEntity>
    member Public : publicSchema
    member SubmitUpdates : unit -> Unit
    member SubmitUpdatesAsync : unit -> Async<Unit>
    nested type public.albumdetails.Individuals
    nested type public.albumdetailsEntity
    nested type public.albums.Individuals
    nested type public.albumsEntity
    ...

    Full name: FSharp.Data.Sql.SqlDataProvider,DatabaseVendor="2",ConnectionString="Server=192.168.99.100;Database=suavemusicstore;User Id=suave;Password=1234;",CaseSensitivityChange="0".dataContext
    type Album = SqlDataProvider<...>.dataContext.public.albumsEntity

    Full name: SuaveMusicStore.Db.Album
    type Genre = SqlDataProvider<...>.dataContext.public.genresEntity

    Full name: SuaveMusicStore.Db.Genre
    type AlbumDetails = SqlDataProvider<...>.dataContext.public.albumdetailsEntity

    Full name: SuaveMusicStore.Db.AlbumDetails
    val getContext : unit -> SqlDataProvider<...>.dataContext

    Full name: SuaveMusicStore.Db.getContext
    SqlDataProvider<...>.GetDataContext() : SqlDataProvider<...>.dataContext


    <summary>Returns an instance of the SQL Provider using the static parameters</summary>

    SqlDataProvider<...>.GetDataContext(transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext


    <summary>Returns an instance of the SQL Provider</summary>
    <param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>

    SqlDataProvider<...>.GetDataContext(connectionString: string) : SqlDataProvider<...>.dataContext


    <summary>Returns an instance of the SQL Provider</summary>
    <param name='connectionString'>The database connection string</param>

    SqlDataProvider<...>.GetDataContext(connectionString: string, transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext


    <summary>Returns an instance of the SQL Provider</summary>
    <param name='connectionString'>The database connection string</param>
    <param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>

    SqlDataProvider<...>.GetDataContext(connectionString: string, resolutionPath: string) : SqlDataProvider<...>.dataContext


    <summary>Returns an instance of the SQL Provider</summary>
    <param name='connectionString'>The database connection string</param>
    <param name='resolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types</param>

    SqlDataProvider<...>.GetDataContext(connectionString: string, resolutionPath: string, transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext


    <summary>Returns an instance of the SQL Provider</summary>
    <param name='connectionString'>The database connection string</param>
    <param name='resolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types</param>
    <param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>
    val getGenres : ctx:DbContext -> Genre list

    Full name: SuaveMusicStore.Db.getGenres
    val ctx : DbContext
    type 'T list = List<'T>

    Full name: Microsoft.FSharp.Collections.list<_>
    property SqlDataProvider<...>.dataContext.Public: SqlDataProvider<...>.dataContext.publicSchema
    property SqlDataProvider<...>.dataContext.publicSchema.Genres: SqlDataProvider<...>.dataContext.publicSchema.public.genres


    <summary> The base table genres belonging to schema public</summary>
    Multiple items
    module Seq

    from FSharp.Data.Sql

    --------------------
    module Seq

    from Microsoft.FSharp.Collections
    val toList : source:seq<'T> -> 'T list

    Full name: Microsoft.FSharp.Collections.Seq.toList
    val getAlbumsForGenre : genreName:string -> ctx:DbContext -> Album list

    Full name: SuaveMusicStore.Db.getAlbumsForGenre
    val genreName : string
    val query : Linq.QueryBuilder

    Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.query
    val album : SqlDataProvider<...>.dataContext.public.albumsEntity
    property SqlDataProvider<...>.dataContext.publicSchema.Albums: SqlDataProvider<...>.dataContext.publicSchema.public.albums


    <summary> The base table albums belonging to schema public</summary>
    custom operation: join var in collection on (outerKey = innerKey). Note that parentheses are required after 'on'

    Calls Linq.QueryBuilder.Join
    val genre : SqlDataProvider<...>.dataContext.public.genresEntity
    property SqlDataProvider<...>.dataContext.public.genresEntity.Genreid: int


    <summary> integer</summary>
    custom operation: where (bool)

    Calls Linq.QueryBuilder.Where
    property SqlDataProvider<...>.dataContext.public.genresEntity.Name: string


    <summary> character varying(120)</summary>
    custom operation: select ('Result)

    Calls Linq.QueryBuilder.Select
    val getAlbumDetails : id:int -> ctx:DbContext -> AlbumDetails option

    Full name: SuaveMusicStore.Db.getAlbumDetails
    val id : int
    type 'T option = Option<'T>

    Full name: Microsoft.FSharp.Core.option<_>
    val album : SqlDataProvider<...>.dataContext.public.albumdetailsEntity
    property SqlDataProvider<...>.dataContext.publicSchema.Albumdetails: SqlDataProvider<...>.dataContext.publicSchema.public.albumdetails


    <summary> The view albumdetails belonging to schema public</summary>
    property SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Albumid: int


    <summary> integer</summary>
    val tryHead : source:seq<'T> -> 'T option

    Full name: Microsoft.FSharp.Collections.Seq.tryHead
    val getAlbumsDetails : ctx:DbContext -> AlbumDetails list

    Full name: SuaveMusicStore.Db.getAlbumsDetails
    Multiple items
    module List

    from FSharp.Data.Sql

    --------------------
    module List

    from Microsoft.FSharp.Collections

    --------------------
    type List<'T> =
    | ( [] )
    | ( :: ) of Head: 'T * Tail: 'T list
    interface IEnumerable
    interface IEnumerable<'T>
    member GetSlice : startIndex:int option * endIndex:int option -> 'T list
    member Head : 'T
    member IsEmpty : bool
    member Item : index:int -> 'T with get
    member Length : int
    member Tail : 'T list
    static member Cons : head:'T * tail:'T list -> 'T list
    static member Empty : 'T list

    Full name: Microsoft.FSharp.Collections.List<_>
    val sortBy : projection:('T -> 'Key) -> list:'T list -> 'T list (requires comparison)

    Full name: Microsoft.FSharp.Collections.List.sortBy
    val a : SqlDataProvider<...>.dataContext.public.albumdetailsEntity
    property SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Artist: string


    <summary> character varying(120)</summary>
    val getAlbum : id:int -> ctx:DbContext -> Album option

    Full name: SuaveMusicStore.Db.getAlbum
    property SqlDataProvider<...>.dataContext.public.albumsEntity.Albumid: int


    <summary> integer</summary>
    val deleteAlbum : album:Album -> ctx:DbContext -> Unit

    Full name: SuaveMusicStore.Db.deleteAlbum
    val album : Album
    member Common.SqlEntity.Delete : unit -> unit
    SqlDataProvider<...>.dataContext.SubmitUpdates() : Unit


    <summary>Save changes to data-source. May throws errors: To deal with non-saved items use GetUpdates() and ClearUpdates().</summary>
    type IntPath = PrintfFormat<(int -> string),unit,string,string,int>

    Full name: SuaveMusicStore.Path.IntPath
    Multiple items
    type PrintfFormat<'Printer,'State,'Residue,'Result> =
    new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result>
    member Value : string

    Full name: Microsoft.FSharp.Core.PrintfFormat<_,_,_,_>

    --------------------
    type PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> =
    inherit PrintfFormat<'Printer,'State,'Residue,'Result>
    new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>

    Full name: Microsoft.FSharp.Core.PrintfFormat<_,_,_,_,_>

    --------------------
    new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result>

    --------------------
    new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>
    Multiple items
    val int : value:'T -> int (requires member op_Explicit)

    Full name: Microsoft.FSharp.Core.Operators.int

    --------------------
    type int = int32

    Full name: Microsoft.FSharp.Core.int

    --------------------
    type int<'Measure> = int

    Full name: Microsoft.FSharp.Core.int<_>
    Multiple items
    val string : value:'T -> string

    Full name: Microsoft.FSharp.Core.Operators.string

    --------------------
    type string = System.String

    Full name: Microsoft.FSharp.Core.string
    type unit = Unit

    Full name: Microsoft.FSharp.Core.unit
    val withParam : key:string * value:string -> path:string -> string

    Full name: SuaveMusicStore.Path.withParam
    val key : string
    val value : string
    val path : string
    val sprintf : format:Printf.StringFormat<'T> -> 'T

    Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
    val home : string

    Full name: SuaveMusicStore.Path.home
    val overview : string

    Full name: SuaveMusicStore.Path.Store.overview
    val browse : string

    Full name: SuaveMusicStore.Path.Store.browse
    val details : IntPath

    Full name: SuaveMusicStore.Path.Store.details
    val browseKey : string

    Full name: SuaveMusicStore.Path.Store.browseKey
    module Admin

    from SuaveMusicStore.Path
    val manage : string

    Full name: SuaveMusicStore.Path.Admin.manage
    val deleteAlbum : IntPath

    Full name: SuaveMusicStore.Path.Admin.deleteAlbum
    namespace Suave
    module Html

    from Suave
    val em : s:string -> Node

    Full name: SuaveMusicStore.View.em
    val s : string
    val tag : tag:string -> attr:Attribute list -> contents:Node list -> Node

    Full name: Suave.Html.tag
    union case Node.Text: string -> Node
    val cssLink : href:string -> Node

    Full name: SuaveMusicStore.View.cssLink
    val href : string
    val link : attr:Attribute list -> Node

    Full name: Suave.Html.link
    val h2 : s:string -> Node

    Full name: SuaveMusicStore.View.h2
    val ul : nodes:Node list -> Node

    Full name: SuaveMusicStore.View.ul
    val nodes : Node list
    val li : (Node list -> Node)

    Full name: SuaveMusicStore.View.li
    val table : x:Node list -> Node

    Full name: SuaveMusicStore.View.table
    val x : Node list
    val th : x:Node list -> Node

    Full name: SuaveMusicStore.View.th
    val tr : x:Node list -> Node

    Full name: SuaveMusicStore.View.tr
    val td : x:Node list -> Node

    Full name: SuaveMusicStore.View.td
    val strong : s:string -> Node

    Full name: SuaveMusicStore.View.strong
    val text : s:string -> Node list

    Full name: Suave.Html.text
    val form : x:Node list -> Node

    Full name: SuaveMusicStore.View.form
    val submitInput : value:string -> Node

    Full name: SuaveMusicStore.View.submitInput
    val input : attr:Attribute list -> Node

    Full name: Suave.Html.input
    val home : Node list

    Full name: SuaveMusicStore.View.home
    val store : genres:string list -> Node list

    Full name: SuaveMusicStore.View.store
    val genres : string list
    val p : (Attribute list -> Node list -> Node)

    Full name: Suave.Html.p
    Multiple items
    module List

    from Microsoft.FSharp.Collections

    --------------------
    type List<'T> =
    | ( [] )
    | ( :: ) of Head: 'T * Tail: 'T list
    interface IEnumerable
    interface IEnumerable<'T>
    member GetSlice : startIndex:int option * endIndex:int option -> 'T list
    member Head : 'T
    member IsEmpty : bool
    member Item : index:int -> 'T with get
    member Length : int
    member Tail : 'T list
    static member Cons : head:'T * tail:'T list -> 'T list
    static member Empty : 'T list

    Full name: Microsoft.FSharp.Collections.List<_>
    val length : list:'T list -> int

    Full name: Microsoft.FSharp.Collections.List.length
    val genre : string
    val url : string
    module Path

    from SuaveMusicStore
    module Store

    from SuaveMusicStore.Path
    val a : href:string -> attr:Attribute list -> (Node list -> Node)

    Full name: Suave.Html.a
    val browse : genre:string -> albums:Db.Album list -> Node list

    Full name: SuaveMusicStore.View.browse
    val albums : Db.Album list
    module Db

    from SuaveMusicStore
    type Album = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity

    Full name: SuaveMusicStore.Db.Album
    val album : Db.Album
    val details : Path.IntPath

    Full name: SuaveMusicStore.Path.Store.details
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Albumid: int


    <summary> integer</summary>
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumsEntity.Title: string


    <summary> character varying(160)</summary>
    val details : album:Db.AlbumDetails -> Node list

    Full name: SuaveMusicStore.View.details
    val album : Db.AlbumDetails
    type AlbumDetails = FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity

    Full name: SuaveMusicStore.Db.AlbumDetails
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Title: string


    <summary> character varying(160)</summary>
    val img : attr:Attribute list -> Node

    Full name: Suave.Html.img
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Albumarturl: string


    <summary> character varying(1024)</summary>
    val div : (Attribute list -> Node list -> Node)

    Full name: Suave.Html.div
    val caption : string
    val t : string
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Genre: string


    <summary> character varying(120)</summary>
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Artist: string


    <summary> character varying(120)</summary>
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Price: decimal


    <summary> numeric</summary>
    System.Decimal.ToString() : string
    System.Decimal.ToString(provider: System.IFormatProvider) : string
    System.Decimal.ToString(format: string) : string
    System.Decimal.ToString(format: string, provider: System.IFormatProvider) : string
    val truncate : k:int -> s:string -> string

    Full name: SuaveMusicStore.View.truncate
    val k : int
    property System.String.Length: int
    System.String.Substring(startIndex: int) : string
    System.String.Substring(startIndex: int, length: int) : string
    val manage : albums:Db.AlbumDetails list -> Node list

    Full name: SuaveMusicStore.View.manage
    val albums : Db.AlbumDetails list
    val deleteAlbum : Path.IntPath

    Full name: SuaveMusicStore.Path.Admin.deleteAlbum
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.albumdetailsEntity.Albumid: int


    <summary> integer</summary>
    val deleteAlbum : albumTitle:string -> Node list

    Full name: SuaveMusicStore.View.deleteAlbum
    val albumTitle : string
    val br : attr:Attribute list -> Node

    Full name: Suave.Html.br
    val notFound : Node list

    Full name: SuaveMusicStore.View.notFound
    val index : container:Node list -> string

    Full name: SuaveMusicStore.View.index
    val container : Node list
    val html : (Attribute list -> Node list -> Node)

    Full name: Suave.Html.html
    val head : (Attribute list -> Node list -> Node)

    Full name: Suave.Html.head
    val title : attr:Attribute list -> s:string -> Node

    Full name: Suave.Html.title
    val body : (Attribute list -> Node list -> Node)

    Full name: Suave.Html.body
    val htmlToString : node:Node -> string

    Full name: Suave.Html.htmlToString
    module App

    from SuaveMusicStore
    module Filters

    from Suave
    module Operators

    from Suave
    module RequestErrors

    from Suave
    module Successful

    from Suave
    module Web

    from Suave
    val html : container:Html.Node list -> WebPart

    Full name: SuaveMusicStore.App.html
    val container : Html.Node list
    val OK : body:string -> WebPart

    Full name: Suave.Successful.OK
    module View

    from SuaveMusicStore
    val index : container:Html.Node list -> string

    Full name: SuaveMusicStore.View.index
    val browse : (HttpContext -> Async<HttpContext option>)

    Full name: SuaveMusicStore.App.browse
    val request : apply:(HttpRequest -> HttpContext -> 'a) -> context:HttpContext -> 'a

    Full name: Suave.Http.request
    val r : HttpRequest
    member HttpRequest.queryParam : key:string -> Choice<string,string>
    union case Choice.Choice1Of2: 'T1 -> Choice<'T1,'T2>
    val getContext : unit -> FSharp.Data.Sql.SqlDataProvider<...>.dataContext

    Full name: SuaveMusicStore.Db.getContext
    val getAlbumsForGenre : genreName:string -> ctx:Db.DbContext -> Db.Album list

    Full name: SuaveMusicStore.Db.getAlbumsForGenre
    val browse : genre:string -> albums:Db.Album list -> Html.Node list

    Full name: SuaveMusicStore.View.browse
    union case Choice.Choice2Of2: 'T2 -> Choice<'T1,'T2>
    val msg : string
    val BAD_REQUEST : body:string -> WebPart

    Full name: Suave.RequestErrors.BAD_REQUEST
    val overview : (HttpContext -> Async<HttpContext option>)

    Full name: SuaveMusicStore.App.overview
    val warbler : f:('t -> 't -> 'u) -> 't -> 'u

    Full name: Suave.WebPart.warbler
    val getGenres : ctx:Db.DbContext -> Db.Genre list

    Full name: SuaveMusicStore.Db.getGenres
    val map : mapping:('T -> 'U) -> list:'T list -> 'U list

    Full name: Microsoft.FSharp.Collections.List.map
    val g : Db.Genre
    property FSharp.Data.Sql.SqlDataProvider<...>.dataContext.public.genresEntity.Name: string


    <summary> character varying(120)</summary>
    val store : genres:string list -> Html.Node list

    Full name: SuaveMusicStore.View.store
    val details : id:int -> WebPart

    Full name: SuaveMusicStore.App.details
    val getAlbumDetails : id:int -> ctx:Db.DbContext -> Db.AlbumDetails option

    Full name: SuaveMusicStore.Db.getAlbumDetails
    union case Option.Some: Value: 'T -> Option<'T>
    val details : album:Db.AlbumDetails -> Html.Node list

    Full name: SuaveMusicStore.View.details
    union case Option.None: Option<'T>
    val never : WebPart<'a>

    Full name: Suave.WebPart.never
    val manage : (HttpContext -> Async<HttpContext option>)

    Full name: SuaveMusicStore.App.manage
    val getAlbumsDetails : ctx:Db.DbContext -> Db.AlbumDetails list

    Full name: SuaveMusicStore.Db.getAlbumsDetails
    val manage : albums:Db.AlbumDetails list -> Html.Node list

    Full name: SuaveMusicStore.View.manage
    val deleteAlbum : id:int -> WebPart<HttpContext>

    Full name: SuaveMusicStore.App.deleteAlbum
    val ctx : FSharp.Data.Sql.SqlDataProvider<...>.dataContext
    val getAlbum : id:int -> ctx:Db.DbContext -> Db.Album option

    Full name: SuaveMusicStore.Db.getAlbum
    val choose : options:WebPart<'a> list -> WebPart<'a>

    Full name: Suave.WebPart.choose
    val GET : WebPart

    Full name: Suave.Filters.GET
    val deleteAlbum : albumTitle:string -> Html.Node list

    Full name: SuaveMusicStore.View.deleteAlbum
    val POST : WebPart

    Full name: Suave.Filters.POST
    val deleteAlbum : album:Db.Album -> ctx:Db.DbContext -> Unit

    Full name: SuaveMusicStore.Db.deleteAlbum
    module Redirection

    from Suave
    val FOUND : location:string -> WebPart

    Full name: Suave.Redirection.FOUND
    val webPart : WebPart<HttpContext>

    Full name: SuaveMusicStore.App.webPart
    val path : pathAfterDomain:string -> WebPart

    Full name: Suave.Filters.path
    val home : Html.Node list

    Full name: SuaveMusicStore.View.home
    val pathScan : pf:PrintfFormat<'a,'b,'c,'d,'t> -> h:('t -> WebPart) -> WebPart

    Full name: Suave.Filters.pathScan
    val pathRegex : pathAfterDomainRegex:string -> WebPart

    Full name: Suave.Filters.pathRegex
    module Files

    from Suave
    val browseHome : WebPart

    Full name: Suave.Files.browseHome
    val notFound : Html.Node list

    Full name: SuaveMusicStore.View.notFound
    val startWebServer : config:SuaveConfig -> webpart:WebPart -> unit

    Full name: Suave.Web.startWebServer
    val defaultConfig : SuaveConfig

    Full name: Suave.Web.defaultConfig

Show code from this section on GitHub

results matching ""

    No results matching ""