I have a utility class for validating usernames in my ember application and have it setup as specified in the ember-cli docs. I do client-side username validation in several places in my application (components and controllers) so I wanted to pull the validation logic out into a reusable method.
The file is at /app/utils/username-validator.js
and I can successfully include the file in my app by importing it like so: import usernameValidator from 'my-app/utils/username-validator';
This works great so far and I've used the pattern for several utility classes. The problem I'm running into now is that I'd like the username-validator
method to include a check to see if the username already exists.
As I am using Ember-Data I'd like to check the Ember-Data store
. By default, the store appears to only be accessible in controllers and routes. How can I make it accessible in my utility class? All the injection examples I've seen deal with injecting the store into other first class Ember objects like components.
Is it possible to inject the store into a simple utility class as well?
Thank you!
I am using the following versions:
Ember-cli v0.2.6
ember.debug.js:4888 DEBUG: -------------------------------
ember.debug.js:4888 DEBUG: Ember : 1.12.0
ember.debug.js:4888 DEBUG: Ember Data : 1.0.0-beta.18
ember.debug.js:4888 DEBUG: jQuery : 1.11.3
ember.debug.js:4888 DEBUG: Ember Simple Auth : 0.8.0-beta.2
ember.debug.js:4888 DEBUG: -------------------------------
===== Updated with detailed solution based on answer from torazaburo ======
Creating a service works great. Here is how I did it using ember-cli (v0.2.6) and ember v1.12.0
- Create your service inside of
/app/services/<service-name>.js
The service blueprint will look like this (note the name of the service is based on the name of the file):
import Ember from "ember";
export default Ember.Service.extend({
myFunction: function(){
}
});
- Create an initializer for your service in
/app/initializers/<service-name>.js
which is used to inject your service into the different top level Ember objects (such as routes, controllers, components etc). Note that the file name of the initializer should match the file name of your service.
The blueprint for the initializer will look like this:
export function initialize (container, app) {
// Your code here
}
export default {
name: '<service-name>',
initialize: initialize
};
To give a concrete example, lets say your service is called validator
and contains a bunch of validation routines. You want to inject the validator into all controllers, and you also want to inject the Ember Data store into the validator itself. You can do it like this:
export function initialize (container, app) {
// Inject the Ember Data Store into our validator service
app.inject('service:validator', 'store', 'store:main');
// Inject the validator into all controllers and routes
app.inject('controller', 'validator', 'service:validator');
app.inject('route', 'validator', 'service:validator');
}
export default {
name: 'validator',
initialize: initialize
};
serviceName: Ember.inject.service
. Actually, one of the advantages of services is that you don't need global injections in initializers and can just inject them directly wherever you need them. This approach is also what permits you to stub them when testing, which you can't do if you're doing global injections in initializers. – user663031Ember.inject.service
and that looks pretty nice as well. I assume I still need the initializer to inject the store into the validator service though. Is that correct? – Sarus