4

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.

nrw
  • 819
  • 2
  • 7
  • 22

1 Answers1

3

Very good question. The answer is quite simple: add @async directive before your username_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.

akoprowski
  • 3,297
  • 1
  • 18
  • 26
  • This is working _perfectly_ for me. Thanks. :) I pulled this out of a rather cumbersome module; I was unsure how to make the question clear. I'll make sure my next examples are compile-ready. – nrw Oct 12 '11 at 08:26