The Setup
I have a (rather standard) form that allows a user to create an account by entering a username and password. When the #username
field loses focus, the database is queried to see if the supplied username is available.
The Problem
Everything works as expected, but the user interface is blocked from when the onblur
event of #username
is triggered until the database returns a value. How can check the database in an asyncronous and non-blocking fashion?
Here's my code (I've pulled most of this code out of example Opa projects):
Types
@abstract type User.ref = string
type User.t =
{ username : string
; passwd : string
}
type User.map('a) = ordered_map(User.ref, 'a, String.order)
Database
db /user : User.map(User.t)
Form
<form>
<input id=#username type="text" onblur={_ -> username_available() } placeholder="username" />
<input id=#password type="password" placeholder="password" />
</form>
Actions
username_available() : void =
user = Dom.get_value(#username)
match (get_user(user)) with
| { none } -> Log.notice("username available:", "YES")
| { some = _ } -> Log.notice("username available:", "NO")
get_user(username : string) : option(User.t) =
match ?/user[username] with
| { none } -> Option.none
| { ~some } -> Option.some(some)
Thanks for your help.
Very good question. The answer is quite simple: add
@async
directive before yourusername_available
function. It is still somewhat experimental and therefore not documented. Any feedback welcome!PS. A detail, but if you include simple code, personally I'd rather see a complete listing in one go (easier to copy&paste&run); possibly with comments in place of headers.