I’m building an addon that needs to read some configuration from the parent app’s config (the parent app provides some options to configure the addon), but it seems that there is no way to import the parent app’s config in addon/ code. I’m guessing it’s because the build process builds that folder separately and eventually concats the separate builds into vendor.js.
Assuming that’s the case, does anyone know of any simple / elegant way to get app config into addon code, without resorting to something like what ember-simple-auth does (maintaining a global Configuration object and injecting the config into that via an initializer at runtime)? Or is that approach the best practice?
Depending on what you have in your addon folder, you can access the app’s config.
For example if you have a Mixin that is used by some object in the consuming that is looked up via the container/resolver (like route, controller, component, view, etc) then you can lookup the app’s config like the following:
modulePrefix: Ember.computed(function() {
var applicationConfig = this.container.lookup('config:environment');
return applicationConfig.modulePrefix;
})
That’s helpful for most of my use cases, but one scenario that comes to mind is a service. It’s just a simple Ember.Object, with no reference to the container. I could inject one via an initializer, but is there a more elegant way in that scenario?
Anything looked up via the container, gets a container. So if your service is either injected into other items (controllers, routes, etc) or looked up via container.lookup('service:foo') it will have a container property set on it.
How is your service integrated into the rest of the application?
I tried using this today on Ember 1.11.3 with a mixin that I was adding to a route, but got the following error:
Failed to create an instance of 'config:environment'. Most likely an improperly defined class or an invalid module export
In my-fancy-project/addon/mixins/foo.js:
import Ember from 'ember';
export default Ember.Mixin.create({
beforeModel: function() {
let config = this.container.lookup('config:environment');
// ...
}
});
I also tried calling this.container.lookup('config:environment') straight from my application’s route, but also got the same error. Any ideas for what might be causing this?
Is this possible with helpers? I’m attempting to build an addon that only outputs DOM within configured environments, but haven’t been able to figure out a) how to inject the environment within the addon code or b) how to test it.
It goes without saying that this is absolutely trivial when done within the context of an actual application. I’m just having trouble extracting that behavior to an addon.
@steven_ferguson the reason it requires container.lookupFactory is because the config is just a simple POJO singleton, but isn’t registered as such (i.e. it doesn’t register with the instantiate: false option).
When you call container.lookup('foo:bar'), it assumes that the foo/bar module will contain a “class” and it will try to instantiate that class. When that fails (in this case, because ‘config/environment’ turns out to be a POJO, not an Ember.Object), it fails with the error message you saw.
It looks the config is pulled via a simple resolver lookup by filepath - nothing actually explicitly registers the config AFAIK. This could be considered a bug, perhaps, but I know there are rumblings of a significant overhaul of the CLI’s approach to config coming down the pipe.
@rwjblue could you comment on that? Is it worth submitting a PR to somehow register the config as a singleton, or should we just hold off for the rumored config overhaul?
I was able to get this working in my service by doing the suggested this.container.lookupFactory('config:environment'). However, I have to set it as a property either in a method or in a computed property. I dont know of a way to import config from 'configLocation'
Now that lookupFactory is no longer available how can I lookup ‘config:environment’ in an instance initializer written in an addon? I’m running into the same error as @steven_ferguson
Failed to create an instance of 'config:environment'. Most likely an improperly defined class or an invalid module export
My code:
function initialize(appInstance) {
var environment = appInstance.lookup('config:environment').get('environment');
The ember-get-config addon seems to make the config available by looking through require.js’s namespace, something I’m not comfortable with. But @davewasmer’s point on registering it as a singleton by the CLI sounds like something that’s worth considering.
// reliable way to get the config?
var configName = Object.keys(window.requirejs.entries).filter((entry) => {
return entry.match(/\/config\/environment/);
})[0];
var config = window.requirejs(configName).default;
This deprecation
now prevents us from using lookupFactory, and I couldn’t get @nullnullnull’s addon to work for some reason. Anyway, hope it helps someone some day.