Docs

Everything You Need to Know

State

API

State

new State(data)

This is a factor that creates a State object for you based on the options you provide. It takes two arguments, the data to encapsule in the state, and a handle to use as its identifier. The state uses the handle to inform the system when it has changed. Mediators listen for this handle and react when it is dispatched.

State objects can hold either an object of key-value pairs, or a array of objects. Depending on the contents, different methods will work. Array methods will not work with an object state and object methods will not work with a array state. However, some methods are share by both states:.

After putting your data in a State object, you can dispose of it if you want to free up memory:

// Create a new State object:
const MyState = new Component(myData)
// Set the data for garbage collection:
myData = null

State objects can hold two kinds of data: a single object of properties and values, or an array of objects. Dependeing on which of these two a State object holds, it exposes different methods for you to use. We'll first look at the State object methods of a object, then at those for an array.

State of Single Object Data

When state holds a single object of properties and values, the State object exposes the following methods:

get

get(property?)

This method lets you get the value of the provided property if it exists on the object stored in the State object. If no property is provided, it returns the comple object of data.

// Get the value of `name`:
const name = myState.get('name');

// Get all the State object's data:
const data = myState.get()

set

set(property, data)

This method lets you set a property and value on the State object's data. If the property already exists, its value will be updated to that provided by this method. If the property does not currently exist on the State object's data, it will be added.

// Update the State object's name property:
myState.set('name', 'John Doe')

// Add a new property to the State object's data:
myState.set('age', 32)

remove

remove(property)

This method lets you remove a property from the State object's data.

// Remove `age` from the State object:
myState.remove('age')
myState.get('age') // returns undefined

merge

merge(object)

This method lets you merge an object into the State object's data. If any of the properties of the object being merged into the State object already exist on the State object, they will be replaced with those of the merged object. And any properties unique to the merged object will be added to the State object.

// Merge an object into the State object:
const person = {
  name: 'Joe Bodoni',
  age: 32
}
const personState = new Component(person)
const obj = {
  age: 40,
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
}
// Merge the object into the State object:
personState.merge(obj)
// personState now:
{
  name: 'Joe Bodoni',
  age: 40,
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
}

mixin

mixin

This method lets you extend a State object with the properties of the provided object. Unlike mixin, if the properties of the object already exist on the State object, they will not be replaced. Only properties that are not currently on the State object will be added.

In the following example, notice how the final State object only received properties that were new after the mixin.

// Mixin an object into the State object:
const person = {
  name: 'Joe Bodoni',
  age: 32,
  hobby: 'sleeping'
}
const personState = new Component(person)
const obj = {
  age: 40,
  hobby: 'eating',
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
}
// Mixin the object into the State object:
personState.mixin(obj)
// personState now:
{
  name: 'Joe Bodoni',
  age: 32,
  hobby: 'sleeping'
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
}

State of Array of Objects

When a State object holds an array of objects, the State object exposes the following methods:

get

get()

This method lets you get all of the State object's data. Since this is an array of objects, that is what you will get.

// Get the State object's data:
const data = myState.get()

getPropAt

getPropAt(property, position)

This method lets you get the value of a property at the specified position in the State object's array. It takes two arguments: the property and position in the array.

// Get the property at position:
const name = personState.getPropAt('name', 11)
console.log('The name is: ' + name)

If you use a negative number as a position, that will count back from the end of the collection. So, a position of -1 would be the last item in the collection, -2 would be the next to last, etc.

setPropAt

setPropAt(property, value, position)

This method lets you set the value of a property at the specified position in the State object's array. It takes three arguments: the property, the value for the property, and the position in the State object's array.

// Set the value of a property:
personMode.setPropAt('name', 'John Doe', 21)

If you use a negative number as a position, that will count back from the end of the collection. So, a position of -1 would be the last item in the collection, -2 would be the next to last, etc.

push

push(data)

This method lets you push data onto the State object's data. This works like the Array.push method.

// Push some data onto the State object:
myState.push({name: 'Joe', age: 22})

pop

pop()

This method lets you pop the last item off of the State object, just like Array.pop.

// Pop the last item from the State object:
const lastPerson = peopleState.pop()
console.log(lastPerson.name)

unshift

unshift(data)

This method lets you insert data to the beginning of a State object, just like Array.unshift.

// Insert data at the start of the State object:
peopleState.unshift({
  name: 'Susan',
  age: 25
})

shift

shift()

This method lets you pop the first item off of a state array.

// Pop the first item from the State object:
const firstPerson = peopleState.shift()

slice

slice(start, end)

This method lets you get a slice of the State object's data. This works the same as Array.slice by returning a new array and does not affect the integrity of the State object's data. Note: the start and end value are zero-based.

// Get a slice of the State object:
const tenPeople = peopleState.slice(0, 9)
peopleView.render(tenPeople)

splice

splice(start, end, data)

This method lets you splice your State object's data. This works the same as Array.splice, so it does directly manipulate the State object's data. Splicing allows you to insert new content into the array, remove a chunk of the array or replace a range of the array with new data. Note: the start and end value are zero-based.

// Get a chuck of the State object:
const chuck = productsState.splice(9, 19, newProducts)

If you have multiple items you want to slice into the State object, do not try to do so as an array, as the array itself will be inserted. Instead provides the items individual as arguments after the end position separated by commas.

insert

insert(position, data)

Like splice, this method lets you directly insert data into the State object. You provide the position to insert at and the data to insert. Note: the position value is zero-based.

// Insert data into State object:
myProducts.insert(20, {name: 'Sam', age 40})

If you have multiple items you want to insert into the State object, do not try to do so as an array, as the array itself will be inserted. Instead provides the items individual as arguments after the insert position separated by commas.

pluck

pluck(property)

This method lets you pluck all the values of a property from the State object. You might, for example, want to get all the prices of a State object of products, or the last names of all costumers in a State object. Just provide the property you want and this method will return the values as an array.

// Get prices from State object:
const prices = prodoctsState.pluck('price')
prices.sort().reverse()
pricesView.render(prices)

find

find(callback)

This method works the same as Array.find. Its callback can perform any kind of operation on any property to determine whether to return the object or not. This is similar to the State object's getPropEquals, but more versatile. If you need to performs some complicated test to determine whether to get the object by a property, this is the version to use.

// Find a State object's object by last name:
const john = peopleState.find(function(person) {
  return person.firstName === 'John' && person.last !== 'Thompson'
})

indexOf

indexOf(value)

This method works the same as Array.indexOf. As such, it is only works if the State object's data is an array so simple values. If the State object holds an array of objects, then use findIndex go get the object's index value.

// Get the index of a value in the State object:
const index = namesState.indexOf('Joe')

findIndex

findIndex(callback)

This method works the same as Array.findIndex. You provide a callback to test the wether to return the index of an object.

// Get index of object in State object:
const index = peopleState.findIndex((person) => person.firstName === 'Joe' && person.lastName !== 'Macaroni')

forEach

forEach(callback)

This method works the same as Array.forEach. It allows you to run a callback against every item in the State object. You can also directly manipulate the data of that iteration, changing the content of the State object.

// Change all last names to uppercase:
peopleState.forEach((person) => person.lastName.toUpperCase())

filter

filter(callback)

This method works the same as Array.filter. It allows you to run a callback against every item in the array and return a new array based on the results.

// Filter people by age:
const youngPeople = peopleState.filter((person) => person.age < 30)
youngPeopleView.render(youngPeople)

map

map(callback)

This method works the same as Array.map. It allows you to run a function against every item of the array and returns a new array based on the outcome of that callback. Unlike forEach, map does not let you affect the State object's data directly but instead returns a new array with those changes.

// Update prices with new tax rate:
const updatedPrices = productsState.map((product) => updateWithNewTax(product.price))
pricesView.render(updatedPrices)

reverse

reverse()

This method works the same as Array.reverse. However, it also works with arrays of objects.

// Reverse the State object's data:
pricesState.reverse()
// Render the new price order
// in view bound to this State object:
pricesView.render()

sort

sort(callback)

This method works the same as Array.sort. You must provide a callback to test the values of the State object's objects for the sort order.

// Sort last names in ascending order:
peopleState.sort(function(person1, person2) {
  if (person1.lastName.toLowerCase() < person2.lastName.toLowerCase()) {
    return -1
  } else if(person1.lastName.toLowerCase() > person2.lastName.toLowerCase()) {
    return 1
  }
});
// Re-render view bound to this State object:
peopleView.render()

orderBy

orderBy(property1, property2?)

This method lets you sort a State object based on various sort criteria. For example, you could sort a State object by first name, last name and age. The default sort order is ascending, but you can change the sort order to descending by prefixing a property with a hyphen.

// Order State object by first and last names:
peopleState.orderBy(firstName, lastName)
// Re-render view bound to this State object:
peopleView.render()
// Order State object by age with oldest first:
peopleState.orderBy(-age)
peopleView.render()

concat

concat(newArray)

This method works the same as Array.concat. When you concat an array of new objects to a State object, the content of the array is added to the mode, not the array itself. This is useful if you do a non-destructive operation on an array and got a new copy back which you want to add to a State object.

// Concat new data to the State object:
const newPeople = [
  {firstName: 'Homer', lastName: 'Simpson'},
  {firstName: 'Marge', lastName: 'Simpson'},
  {firstName: 'Bart', lastName: 'Simpson'},
  {firstName: 'Lisa', lastName: 'Simpson'},
]
peopleState.concat(newPeople)
// Re-render view bound to this State object:
peopleView.render()

mixin

mixin(newArray)

Like mixin for object property, this method will mixin and array of objects to the State object. If their are any duplicates, they will be eliminated.

// Mixin new data to State object:
productsState.mixin(newItems)
// Re-render view bound to this State object:
productsView.render()

unique

unique()

This method will remove any publicates from the State object. This is useful where the user might have made multiple entries of the same thing without realizing it.

// Remove duplicates from State object:
productsState.unique()
// Re-render view bound to this State object:
productsView.render()

eq

eq(position)

This method lets you get an object from the State object based on its position. This is a zero-based value. You could get the position using findIndex or whatever means you might have.

// Get the tenth person from State object:
const tenthPerson = peopleState.eq(9)

size

size()

This method returns the number of objects in a State object.

// Get the number of products:
const number = cartState.size()
alert('You have ' + number + ' items in your cart.')

dataStore

Rather than using get() on a State object, you can access the object's data directly from its dataStore property. You could also directly manipulate the object's data there, bypassing any reactive methods. However, it's best to use reactive State methods so that bound components get updated. It's also safer to set paused property of a State instance to true, use its reactive methods, set its paused false and invoke the instance renderComponents method. This is just a safer way to manipulate state.

That said, using dataStore is a quick and easy way to get data out of a State object:

// Create State object:
const fruitState = new State(['Apples','Oranges','Bananas'])
console.log(fruitState.dataStore)
// Returns: ['Apples','Oranges','Bananas']

Medhods Shared by Objects and Arrays

The following methods are shared by State objects of objects and arrays.

purge

purge()

This method will delete all data from the State object, leaving only and empty object: {}. After purging a State object, myState.get() will return {}.

// Delete all data from an object in a State object:
myState.purge()
// Check what the State object holds:
myState.get()
// returns {}

replace

replace(data, renderView)

This method allows you to quickly replace all the data in the State object with other data. This is so that you can do some complicated operations on the data before updating the State object. By default using this method does not cause a view to render. However, if you pass any secondary boolean true argument (renderView), the bound view will be rendered with the changes.

// Replace State object data, do not render view:
myState.replace(newData)

// Replace State object data and render view:
myState.replace(newData, true)

paused

myState.paused = true

This is a property on a State instance. Its default value is false. If you set it to true, when you modify the state, it will not trigger a render of its bound components. This is useful where you want to make a number of changes to a component's state without causing a render with each change. Just set the State instance paused property to true and do whatever you need to do with state. When you're done, just run renderComponents on the state instance. It will render the component with its current state. Remember, if you've paused the State instance, set it back to false before running renderComponents on it. The following is a trivial example, but it shows how to pause state, make changes without causing component render, unpausing state and rendering the components with the changes.

// Create State object:
const myState = new State('some stuff')
// Pause State object:
myState.paused = true
myState.set('This is the new value.')
let newText = myState.get()
myState.set(newText.toUpperCase())
// Reset paused to false:
myState.paused = false
// Update bound components
myState.renderComponents()

Check out the pausing-state.html file in the examples folder.

renderComponents

renderComponents()

This method is used internally by State objects to render their bound components when an operation changes the data in the state. You can also use this if you paused a State instance to make some changes and want to update the bound components. This is executable direction on the state instance. Executing this on a State object will cause all components bound to it to be rendered. See the example above for how to use it.