Making Ember Objects More Strict: Only Access Defined Properties

Ember.Object provides a flexible starting point for creating models in a single-page web application. It can hold simple data members, define computed properties that automatically update when dependencies change, run a callback when properties change, and extend parent “classes” to create new types with additional members.

That said, I think Ember can be a bit too flexible at times.

How Much Flexibility is Too Much?

Let’s say I create a model for a blog post using Ember Data:

See the code in the full post.

Then in code later on, I can do the following:

See the code in the full post.

That’s all well and good. But what if later on, I want to set the body of the post, forget I called it ‘text,’ and think I called it ‘body’?

See the code in the full post.

My tests (automated and manual) will probably fail because the post content is not being updated properly, but it may not be immediately clear what the problem is. This issue is further exacerbated by many-word property names:

See the code in the full post.

or when you are dot-chaining in property gets or sets:

See the code in the full post.

If data is undefined, which part is to blame: foo or bar or baz? Again, we can dig in and figure out the answer, but it would be nice if we didn’t have to.

Best Practices

I consider it a best practice to define any property I intend to use at the top of my Ember.Object. If it will be a simple data type, I use something like:

See the code in the full post.

Consequently, I almost never want to get or set a property on an Ember.Object that I did not explicitly define. Ideally, Ember would tell me immediately if I tried to get or set an unknown property and I didn’t intend to do so.

Strict Models

Luckily, it isn’t hard to accomplish this. Ember.Object provides two functions, unknownProperty() and setUnknownProperty(), which can be used to create “strict” models. The presumed intention of these functions is to allow dynamic execution based on the string value of the property name to be retrieved or set.

However, we can repurpose them to make our Ember.Object models more strict. We can implement unknownProperty() and setUnknownProperty() to throw errors providing details of the property meant to be used, which allows us to fail fast and get as close as Ember allows to a locked down, static class.

See the code in the full post.

Now, our first example throws an error when you try to set the wrong property:

See the code in the full post.

The Exception that Complicates the Rule

Actually, it isn’t quite so simple. On some occasions, the Ember framework (and potentially plugins used by your application) may invoke properties you don’t care about or want to declare. Accordingly, you’ll have to allow some property names even if they are not explicitly defined. For these exceptions, you’ll want to use the default behavior (return undefined for get(), and call defineProperty() for set()). This is frustrating, but I don’t think it reduces the value of strict models by an unreasonable amount.

See the code in the full post.

Types, But Not Too Verbose

On my current project, making all of our data transfer objects into strict models has already helped me catch and fix errors more quickly than I would have otherwise. In general, I’d rather have my code throw an error than fail implicitly or silently. And as I wrote about with generating Ember models from C#, even if JavaScript is not statically typed, I’ll nudge it in that direction when I can do so–as long as it doesn’t make my code overly verbose.

Originally published at on October 19, 2016.

Show your support

Clapping shows how much you appreciated Atomic Object’s story.