
Product
Introducing Reports: An Extensible Reporting Framework for Socket Data
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.
ember-state-manager
Advanced tools
An Ember.JS state management solution that is built upon the ideals of ember-state-services.
State management is one of the most complex aspects of large application design and when done wrong often leads to bugs and errors. EmberJS contains 2 high-level avenues for storing state: controllers (long-term state) and components (short-term state). Controllers are singletons and any state you set on them will stay there until your application is reloaded or you override the previous value. Components on the other hand are created and destroyed as they enter/leave the DOM and any state that is set on them will be removed/reset each time they are recreated. As you build more complex applications you will find yourself needing a way to have some sort of middle ground solution. Something that has properties of both long-term state and short-term state.
ember install ember-state-manager
If it is a bug please open an issue on GitHub.
The first thing you will need to do is create your state file(s). All states are expected
to be under app/states and must export an Ember (like) Object. This addon ships with
a blueprint to make this pretty easy.
ember generate state <name> <options...>
Create a new state
--type (object, array, buffered-object, buffered-array)
# Create a state named 'foo' that is an Object
ember generate state foo
ember generate state foo --type=object
# Create a state named 'foo' that is an Array
ember generate state foo --type=array
# Create a state named 'foo' that is a Buffered Object Proxy (requires ember-buffered-proxy to be installed)
ember generate state foo --type=buffered-object
# Create a state named 'foo' that is a Buffered Array Proxy (requires ember-buffered-array-proxy to be installed)
ember generate state foo --type=buffered-array
Once you run the generate command, you will see a new file has been created:
// app/states/foo.js
import EmberObject from '@ember/object';
const State = EmberObject.extend();
State.reopenClass({
initialState(/* model */) {
return {};
}
});
export default State;
You can access a state via the provided service, template helper, or computed macro.
stateManager ServiceThis service gives you full control on accessing and deleting states.
stateForReturns a state object for the given model with the specified state (file) name.
function stateFor(model: Object, stateName: String, options: Object);
Available Options:
bucketName: String: The bucket name to store the state under (optional)createWithoutModel: Boolean: Whether to return a valid
state object even if the model is falsy (defaulted to false).// Example Usage
this.get('stateManager').stateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>', createWithoutModel: true });
deleteStateForDelete the state object for the given model with the specified state (file) name.
Calling stateFor after this method will return a new state object.
function deleteStateFor(model: Object, stateName: String, options: Object);
Available Options:
bucketName<String>: The bucket name to store the state under (optional)// Example Usage
this.get('stateManager').stateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>' }); // old state
this.get('stateManager').deleteStateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>' });
this.get('stateManager').stateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>' }); // new state
{{state-for}} Template HelperYou can access a state in your templates via the {{state-for}} helper which is a
proxy to stateManager.stateFor.
{{state-for model stateName bucketName=bucketName createWithoutModel=createWithoutModel}}
{{-- Example --}}
{{#with (state-for model '<STATE_NAME>' bucketName='<BUCKET_NAME>') as |state|}}
{{#if state.isEditing}}
Editing...
{{/if}}
{{/with}}
stateFor Computed MacroThis addon provides a simple computed property macro which is a proxy to
stateManager.stateFor.
Note: This macro requires container/owner access.
import Component from '@ember/component';
import { stateFor } from 'ember-state-manager';
export default Component.extend({
model: null,
/*
* `stateFor` returns a computed property that provides a given
* state object based on the 'model' property. Whenever model
* changes a new state object will be returned.
*/
state: stateFor('model', '<STATE_NAME>', { bucketName: '<BUCKET_NAME>', createWithoutModel: true })
})
In your state file, you can use the initialState to setup your state object with
initial values.
// app/states/foo.js
import EmberObject from '@ember/object';
const State = EmberObject.extend();
State.reopenClass({
initialState(/* model */) {
return {
text: '',
isEditing: false
};
}
});
export default State;
State bucketing can be super handy if you want to create multiple states for the same model / stateName combo. Lets say we create a default buffered object state:
// app/states/buffered-object.js
import BufferedObjectProxy from 'ember-buffered-proxy/proxy';
const State = BufferedObjectProxy.extend();
State.reopenClass({
initialState(model) {
// Our state now becomes a buffer of the model!
return { content: model };
}
});
export default State;
We can create multiple long lived buffers for the same model.
const bufferA = stateManager.stateFor(model, 'buffered-object', { bucketName: 'A' });
const bufferB = stateManager.stateFor(model, 'buffered-object', { bucketName: 'B' });
We can make changes to either buffers, display them to the user, and let them select which one they like. Once selected, we can apply the changes and save the model.
We can easily create a validation backed buffered object so we can validate changes before we apply them.
// app/states/validated-buffered-object.js
import BufferedObjectProxy from 'ember-buffered-proxy/proxy';
import { buildValidations, validator } from 'ember-cp-validations';
const Validations = buildValidations({ /* ... */ });
const State = BufferedObjectProxy.extend(Validations);
State.reopenClass({
initialState(model) {
// Our state now becomes a buffer of the model!
return { content: model };
}
});
export default State;
const buffer = stateManager.stateFor(model, 'validated-buffered-object');
await buffer.validate();
if (buffer.get('validations.isValid')) {
buffer.applyChanges();
buffer.get('content').save();
}
FAQs
An Ember state management solution
We found that ember-state-manager demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.