
Security News
Another Round of TEA Protocol Spam Floods npm, But It’s Not a Worm
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.
ember-microstates
Advanced tools
In Ember components, managing state has historically been a manual process. We render values in our templates, and then inside our components, controllers and routes, we write custom code to oversee each state transition. Forexample, how often have you seen or written an action like this?
actions: {
toggleOpen() {
this.toggleProperty("isOpen");
}
}
and then bound it to an event in your template:
<button onclick={{action "toggleOpen"}}>Toggle</button>
<div class={{if isOpen "showing" "hidden"}}>
Here is the content !~!REVEALED!~!
</div>
In this case, a boolean value is stored on the isOpen property of
the component, and the toggle action transitions it from its current
value to its logical inverse. But if we think about it, all boolean
values by their vary nature can be toggled.
And really, the same can be said about any data type you care to choose, be it a list, number, string or what have you. The point is that the set of valid state transitions is implicit to type of data you have. So why should we have to implement state transitions at all?
What if you could declare the type of data that you had, and then all the action implementations were just written for you?
That's where microstates come in. They take advantage of the fact that the operations which can be performed on a piece of data are fully known before hand so that you can simply declare which operations correspond to which HTML events.
Using Microstates, we would rewrite the example above using the
Boolean helper like so:
{{let isOpen=(Boolean false)}}
<button onclick={{action isOpen.toggle}}>Toggle</button>
<div class={{if isOpen "showing" "hidden"}}>
Here is the content !~!REVEALED!~!
</div>
There is no accompanying JavaScript here because there doesn't need to be. We know we have a boolean, so why would we need code to manage it by hand?
The same applies for other data types as well, and there are currently microstates for objects, lists, strings and numbers.
No.
Unlike templating power-ups like Ember Truth Helpers and Ember Composeable Helpers (which are awesome by the way), Ember Microstates is not about deriving new state from existing state.
Instead, it is about declarativly mapping transitions of one state to the next. So:
{{action "toggleOpen"}}
becomes
{{action isOpen.toggle}}
Notice how the value being referred to is explicit and obvious as
opposed to hidden in a component .js file. Notice also how the
transition to be invoked is explicit and obvious without the need to
look any where else. Power is gained. Intention is revealed.
To see more exhaustive examples of microstates in action, you can start the dummy app and have a look at the demos found here to see at least one case of each microstate.
What if you're not satisfied with the microstates provided? What if you want more?
This is currently an advanced topic. Our plan is to make the story around building your own microstate helpers a lot easier, but for now it involves some leg-work.
That said, it is possible today, and if you're interested your best
bet is to hit up #e-microstates channel in the ember community
slack.
(Object (hash [attr=value])
(List array)
(Boolean true|false)
(String string)
(Number number)
(Select array [selection=array|value] [multiple=false|true])
The object state serves as the base for all other microstates. The transitions that are available to object are available to all other types:
{{let car=(Object (hash make="Ford" model="Mustang" year=1967))}}
assign(attributes)Transitions this microstate into a new version that has attributes
merged in with its current key-value pairs. Any key-values already present are
retained. For example if we use our car, which has "make", "model", and "year"
properties, we can specify an action that will assign to the "model" and "year",
but leave the "make" as is.
<button onclick={{action car.assign (hash model="Taurus" year=2015)}}>
Make Sedan
</button>
{{!clicking will result in {make: 'Ford', model: 'Taurus', year: 2015}}}
delete(key)Remove a key (and subsequent value) from this object. For example, to delete the "year" property from our car:
<button onclick={{action car.delete "year"}}>
Remove Year
</button>
{{!clicking will result in {make: 'Ford', model: 'Mustang'}}}
put(key, value)Add property with a given name and value to the object. It will update the property with the given value if it already exists.
<button onclick={{action car.put "color" "blue"}}>
Add color
</button>
set(object)Replace current object microstate with a new object microstate from given hash.
<button onclick={{action car.set (hash make="Toyota" model="Supra" year="1982")}}>
Update car
</button>
List microstate represents an ordered collection of values.
{{let numbers=(List (array 1 2 3))}}
{{each numbers as |item|}}
{{item}}
{{/each}}
concat(list)Makes a new list with all of the items from the given list added to the end of the current list.
<button onclick={{action numbers.concat (array 4 5 6)}}>
Add more items
</button>
pop()Makes a new list the last item removed from current list.
<button onclick={{action numbers.pop}}>
Remove last item
</button>
push(item)Makes a new list with item added to the end of the current list.
<button onclick={{action numbers.push 4}}>
Add 4
</button>
remove(item)Makes a new list the given item removed from the current list.
<button onclick={{action numbers.remove 3}}>
Remove 3
</button>
replace(item, other)Makes a new list with a new item in place of the given item in the current list.
<button onclick={{action numbers.replace 3 6}}>
Replace 3 with 6
</button>
shift()Makes a new list with the first item of the list removed.
<button onclick={{action numbers.shift}}>
Remove first
</button>
unshift(item)Add an item to the beginning of the list.
<button onclick={{action numbers.unshift 7}}>
Add to the beginning
</button>
set(list)Replaces current list with given list.
<button onclick={{action list.set (array 4 5 6)}}>
Replace the list
</button>
Boolean represent a true or false value.
{{let isYa=(Boolean true)}}
{{#if isYa}}
Yes
{{else}}
No
{{/if}}
toggle()Transition the Boolean microstate to opposite of it's current value.
<button onclick={{action isYa.toggle}}>
Flip the value
</button>
set(boolean)Transition the microstate to give the value.
<button onclick={{action isYa.set false}}>
Make false
</button>
StringRepresents a String object.
{{let message=(String 'hello world')}}
{{message}}
concat(string)Add string to the end of the existing value.
<button onclick={{action message.concat '!!!'}}>
Exclaim!!!
</button>
set(string)Replace current value with new string.
<button onclick={{action message.set 'I come in pieces'}}>
Confuse
</button>
Represents a numerical value.
{{let age=(Number 34)}}
{{age}}
increment()Make a new number that's greater than current number by 1.
<button onclick={{action age.increment}}>
Increment
</button>
decrement()Make a new number that's less than current number by 1.
<button onclick={{action age.decrement}}>
Decrement
</button>
add(number)Make a new number that's greater than current value by provided amount.
<button onclick={{action age.add 1}}>
Increase by one
</button>
subtract(number)Make a new number that's lesser than current value by provided amount.
<button onclick={{action age.subtract 1}}>
Decrease by one
</button>
multiply(number)Multiply the value by given number.
<button onclick={{action age.multiply 10}}>
Multipy by 10
</button>
divide(number)Divide the value by given number.
<button onclick={{action age.divide 10}}>
Divide by 10
</button>
set(number)Replace the value with given number.
<button onclick={{action age.set 21}}>
Set age to 21
</button>
The Select microstate represents a set of distinct options from which choices can be made. For any given value in the set, it tracks whether that value has been selected for inclusion. You would use it when you want to build something analogous to a set of checkboxes, radio buttons, or select box.
The select state has a list of options wrapping each choice to track
where that option is selected, and also to contain the actions for
either selecting or deselecting that option (toggle, select, and deselect)
It comes in two varieties: multiple selection and single
selection. With multiple selection, the number of possible choices is
unlimited and the value of the selection property is an array of the
selected values. With a single selection, choosing one option means
that all other options will be deselected. Furthermore, the value of
the selection property is a single value.
Head's up! The actions for changing which options are selected live on the options themselves and not the actual select microstate.
{{let animals=(Select (array 'cat' 'dog' 'bird'))}}
<h3> Choose your favourite pet </h3>
{{#each animals as |option|}}
<button onclick={{action option.toggle}}>{{option}}</button>
{{/each}}
{{let animals=(Select (array 'cat' 'dog' 'bird') multiple=true)}}
<h3> Choose animals you like </h3>
{{#each animals as |option|}}
<input type="checkbox" checked=option.isSelected onclick={{action option.toggle}}> {{option}}
{{/each}}
<h3> Stefan's Choice </h3>
{{let animals=(Select (array 'cat' 'dog' 'bird') selection='bird')}}
option.toggle()Make a new selection with option having the opposite of its current
selection state. In other words, If this option is currently selected,
it will become unselected. If it is unselected, it will become
selected.
{{#each animals as |option|}}
<button onclick={{action option.toggle}}>{{option}}</button>
{{/each}}
option.select()Make a new selection with this option selected. If this is a single select, then any other currently selected option will become unselected as a result.
{{#each animals as |option|}}
<button onclick={{action option.select}}>{{option}}</button>
{{/each}}
option.deselect()Make a new selection with this option unselected.
{{#each animals as |option|}}
<button onclick={{action option.deselect}}>{{option}}</button>
{{/each}}
git clone this repositorynpm installbower installember servernpm test (Runs ember try:testall to test your addon against multiple Ember versions)ember testember test --serverember buildFor more information on using ember-cli, visit http://ember-cli.com/.
FAQs
Data Down, Actions Up: at the molecular level.
We found that ember-microstates 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.

Security News
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.

Security News
PyPI adds Trusted Publishing support for GitLab Self-Managed as adoption reaches 25% of uploads

Research
/Security News
A malicious Chrome extension posing as an Ethereum wallet steals seed phrases by encoding them into Sui transactions, enabling full wallet takeover.