The template language
Errors
What the parser reports, and what to do about it.
The parser reports a mistake with its line and column, and inside template! as a compiler error at the offending token. These are the messages it gives, each produced here by running the parser on the example shown, so the wording is exactly what you'll see.
Errors at run time, when an expression meets the wrong kind of value, name the element they happened in: '*' needs a number, not text "a" in <p>. An error in a state's first value fails the component's first render; an error in a let or a handler is reported to the console, and the let reads as null.
Messages
| Template | Message | What to do |
|---|---|---|
p "unclosed | line 1, column 3: unterminated string | Close the string with ". |
p "a" ~ | line 1, column 7: unexpected character '~' | Remove the character, or put it in a string. |
div { p "a" | line 1, column 12: expected '}' to close 'div', found end of template | Add the missing }. |
p(class "x") | line 1, column 9: expected an attribute name, found string "x" | Write name: value between an attribute's name and value. |
p "a" { span "b" } | line 1, column 7: 'p' has text and children; give the text its own node inside the braces: p { "…" … } | An element has text or children, not both: put the text in its own node inside the braces. |
button(@click: "go") | line 1, column 16: expected an event handler reference, found string "go" | An event's handler is a name, or a call: @click: go. |
li(@click: pick(x -> x)) | line 1, column 16: a handler's arguments are values, not lambdas | A handler's arguments are values; compute them, or move the lambda into a standard function. |
let n = len(1, 2) ⏎ p "{n}" | line 1, column 9: 'len' takes 1 argument (len(list or text)), not 2 | Give the standard function the arguments its signature lists. |
let n = map([1], 2) ⏎ p "{n}" | line 1, column 9: 'map' needs a lambda there (map(list, x -> value)) | Pass a lambda where the function expects one: map(xs, x -> x * 2). |
let n = trim(x -> x) ⏎ p "{n}" | line 1, column 9: 'trim' doesn't take a lambda there (trim(text)) | Only some arguments of some functions are lambdas. |
let n = f(x -> x) ⏎ p "{n}" | line 1, column 9: 'f' isn't a standard function, so it can't take a lambda | Only standard functions take lambdas. |
let a = !x == "y" ⏎ p "{a}" | line 1, column 12: cannot negate a comparison; use '!=' instead (or parentheses: (!a) == b) | Write x != "y", or (!x) == "y". |
for x, i in xs { p "{x}" } | line 1, column 6: expected 'in', found ',' | A loop binds one name; use event.index, or a function's index parameter. |
state a = 1 ⏎ state a = 2 | line 2, column 1: 'a' is declared twice | Give each declaration its own name. |
let a = 1 ⏎ on f = a <- 2 | line 2, column 1: 'a' isn't a state declared here, so it can't be set | Only a state can be set: declare a with state. |
on f = count + 1 | line 1, column 8: a handler's step is state <- value or a command (emit, navigate, get, post, put, patch, delete, reload, prevent), not count + 1 | A step sets a state (count <- count + 1) or runs a command. |
let a = b ⏎ let b = 1 | line 1, column 1: 'a' reads 'b', which is declared at or after it | Declare a name before what reads it. |
state event = 1 | line 1, column 7: 'event' can't be declared | Choose another name: event is the event in handlers. |
on f(event) = navigate("/") | line 1, column 6: 'event' can't be a parameter | Choose another parameter name. |
load x = 1 | line 1, column 10: a load is a request: get(url) or post(url, body), with an optional record of options | A load is a request: load x = get(url). |
load x = get() | line 1, column 10: 'get' in a load takes a URL and an optional record of options | Give get a URL, and optionally a record of options. |
on f = post(u, b, done) | line 1, column 1: 'done' isn't an on handler declared here | Declare the handler (on done(answer) = …), or leave the name out. |
on f = reload(x) | line 1, column 1: 'x' isn't a load declared here | reload takes the name of a load declared in the template. |
on f = get(u, "x") | line 1, column 8: 'get' names a handler here, not "x" | Pass handler names, not values, after a request's URL. |
on f = post(u) | line 1, column 8: 'post' is written post(url, body, ok, err), the handlers optional | Give post a URL and a body. |
every 1 when x | line 1, column 15: expected '=', found end of template | End a timer's head with = and its steps. |