I’m building an addon that’s mostly UI blocks. From the dummy app, I’ve validated “everything works.”
Within the dummy app, I want to show different layout options (css styles for minifiedNav or fullWidthContainer vs fixedWidthContainer, etc.) so I’ve created a “Settings” service to handle state. It’s working just as I want it to at the moment.
The next thing I can’t figure out is how to connect application environment configs to my service to prepopulate the app owner’s intention.
All the documentation I can find is from the app’s perspective (Configuring Your App - Configuration - Ember Guides for example) and includes the app’s name which doesn’t work here (my addon name doesn’t work either).
But it feels like I have a Rube Goldberg mess of an operation I’d expect many Addon Developers want to do… I just can’t find the documentation! Any pointers?
Thanks @ef4, that’s much simpler. I’ll give that a go and see if it works.
Slightly related follow up questions:
Is there a simpler way to “track everything in this object” other than adding @tracked to every attribute?
deepmerge as a lib is proving problematic. It doesn’t play well with ember install and I’m getting inconsistent update results. Is there a better way to deep merge an object? Object.assign seems like it’s a shallow copy.
For (1) you can use TrackedObject from tracked-built-ins, though I would suggest using it with care: most things in an app are better represented with a TrackedMap (when you have actual map/dictionary semantics) or a class with tracked properties (where the shape is well known ahead of time).
You can use any library for merging, install it directly via npm or yarn and as long as you also have ember-auto-import you can import it directly into your code.
import Service from '@ember/service';
import { getOwner } from '@ember/application';
import {action} from '@ember/object';
import {TrackedObject} from "tracked-built-ins";
import { merge } from 'lodash';
export default class SettingsService extends Service {
/* changes are tracked in the app */
appLayout = new TrackedObject({
fixedNavigation: false,
minifyNavigation: false,
boxedLayout: false,
});
/* static data that won't change */
appMeta = {
logo: "img/logo.png",
title: "Example Application"
};
@action toggleSetting(path) {
const parts = path.split('.');
let currentObject = this[parts[0]];
parts.slice(1, -1).forEach(part => { currentObject = currentObject[part] });
currentObject[parts.slice(-1)] = !currentObject[parts.slice(-1)];
}
constructor(app) {
super(app);
let config = getOwner(this).resolveRegistration("config:environment").MyAddon || {};
merge(this, config);
}
}
This lets anyone including my adding use the MyAddon config namespace to override these values WHIILE ALSO allowing for user level settings toggled via a button: