This is one of those daily occurences I see in the official Aurelia Gitter chatroom (not a member, come say hello here).
You are using a bindable in your application to add in binding, whether it be one-way, two-way or one-time. You might define your bindable inside of your custom element viewmodel like this:
import {bindable} from 'aurelia-framework';
export class MyNameCustomElement {
@bindable someNameValue = '';
}
One would naturally assume that to use this attribute, you would reference it like this:
<my-name someNameValue="Dwayne"></my-name>
This is wrong and will not work.
You might be wondering why it doesn’t work and the simple explanation is: the HTML spec has no concept of casing. Everything is treated as lowercase (except text and HTML values inside of a node).
To counteract this, we use kebab-casing. If you are not familiar with the term, it means you take your bindable property, you lowercase it and separate each word with a hyphen, like a URL slug (see the URL of this blog post).
The above invalid example then becomes the following:
<my-name some-name-value="Dwayne"></my-name>
Another solution could be to define your bindable as all lowercase, but this would look messy for long bindables, taking the above example and defining it all lowercase, you would define and use it like this:
import {bindable} from 'aurelia-framework';
export class MyNameCustomElement {
@bindable someNameValue = '';
}
<my-name some-name-value="Dwayne"></my-name>
Where The Confusion Stems From
As I explained earlier, the HTML specification is not case sensitive. Everything is lowercase and because Aurelia adheres to the specification, it assumes your attributes are lowercase and kebab-case.
The real confusion stems from the inconsistency between how you reference a bindable in your viewmodel versus how you reference it in your HTML templates.
When referencing a bindable inside of your viewmodel:
Because Javascript does have the concept of case sensitivity, if you define a bindable using camelCase, you need to refer to it the same way it was defined.
import {bindable} from 'aurelia-framework';
export class MyNameCustomElement {
@bindable someNameValue = '';
attached() {
// After 5 seconds, add a name
setTimeout(() => {
this.someNameValue = 'Secret Name';
}, 5000);
}
}
Referencing the same bindable in your HTML:
Parroting what we said earlier, in HTML we use kebab-case.
<my-name some-name-value="Dwayne"></my-name>
Conclusion
That’s it. Remember your bindable values when used as attributes if you are defining them as camelCase, they become kebab case when used in HTML.
Typo: One would naturally (awesome) assume
Hah, just ran into this trying to name a bindable “logoutURL”. Hmm. Doesn’t work. I guess I’ll try “logout-url”. Nope. Actually Aurelia expects logout-u-r-l as the attribute name. The downside of this kind of “magic” in frameworks is sometimes the magic goes wrong in confusing ways.