Components with External Data (typeahead) - Data Access in Component or Controller?


I’m working on creating a new component for implementing a typeahead.js autocomplete component, using typeahead.js and I’m not sure the best practice for where to put data access when I want to integrate the autocomplete results with an API endpoint. I want the autocomplete to be based on an external URL, and I’ve been able to set that up and get everything working, but I’m not sure which design is best and the “Ember way”.

Option 1: Ember handles the data access, not typeahead.js. The component gets bound to a controller action and a controller property, and that controller action is responsible for loading the data and pushing the results to the controller property.

I like this because if I wanted to, I can expand this and do any manipulation of data or results within the controller. However, I don’t like the idea of a component relying on the controller to have an action. This feels like an anti-pattern as components should not be dependent on controllers.

See jsbin here:,js,output

Option 2: Typeahead.js handles data access, not Ember. The component gets bound to a controller property with data, or an API endpoint string is passed to the component which is then used by typeahead.js.

I like this because all the data access, caching, filtering, rate limiting, etc. is handled by the typeahead.js library, and the component is truly encapsulated.

The downside is that data access isn’t integrated into the Ember run loop, though I’m not sure if that’s an issue, and also because I can’t customize the returned data without customizing the component. Again, I’m not sure if those two points are worth anything at this point though. Also, I’m not sure I like the idea of passing in a url endpoint string when defining my component in markup.

See jsbin for option 2 here:,js,output

For both examples, type “red” to see results.

Any thoughts or comments? I’m leaning towards option 2, simply because option 1 feels like a lot of hacks of both typeahead.js as well as having to integrate into the run loop.