-
Notifications
You must be signed in to change notification settings - Fork 0
State Management
State
is a way to mannage the "state" of your application. It is the single source of truth and holds the whole state tree. In truth, it is just an object. To change the state, you must Commit a mutation to it. For instance if you have a username inside your View Controller. And you display it as a heading in your template.
<template>
<h1>{{username}}</h1>
</template>
ActiveJS.newController("State_Management", {
el: "#app",
Data() {
return {
username: "John"
}
}
})
Now if you update username
via a method inside your View Controller
. This is all good, but what happens when you change to another view and come back? The username
property will now be set back to it's initial value when you load the view. This is where State
comes into the picture!
Inside the ./public
at the root of the application. you'll find a file called app.state.js
. In this file you'll find an exported object which contains four properties ( state, getters, mutations, actions
). Read more to find out what each of these properties do.
export default {
"model": {
// where you store global data
},
"getters": {
// where you store your getters for properties in the model
},
"mutations": {
// where you store your setters for properties in the model
},
"actions": {
// where you store your async methods
},
};
The context
is an object with access to your properties inside your state object. It is passed to all methods
inside your getters, mutations and actions
. The context object
allows you to get properties out of your state or call a method from your mutations or actions. Below is a table showing every property inside the context Object
.
Propery | Type | Description | ( --------- ) |
---|---|---|---|
$model | Object |
A reference to the model object |
example |
$mutaions | Object |
A reference to the mutaions object |
example |
$actions | Object |
A reference to the actions object |
example |
Get | Method |
Allows you to call a method inside your getters object |
example |
Commit | Method |
Allows you to call a method inside your mutations object |
example |
Dispatch | Method |
Allows you to call a method inside your actions object |
example |
The model
property is the main object of variables/properties
in which you will be storing and minipulating data. For example you could add a property to the state called users. And this could be an array of user objects.
"model": {
users: [
{name: "James", age: 15},
{name: "Fred", age: 34},
{name: "John", age: 22}
]
}
The getters
property will be an object of methods. The method's job is to get values out of your model
. For example, lets say you want to get the user james out of your array of users we showed you above. You would create a getter
method. Lets call it getUser()
. How do we access the model? Well, all getters get passed the context object and a payload
that you set when calling a getter
. See the example below.
"getters": {
getUser(context, payload) {
const user = context.$model.users.filter(user => {
return user.name == payload.name;
});
return user;
}
}
// using a 'getter' method in your view
ActiveJS.newController("State_Management", {
el: "#app",
Data() {
return {
username: "John"
}
},
methods: {
getUsers() {
ActiveJS.State.Get("getUser", {name: this.username});
}
}
})
The mutations
property holds all your methods that update or change
your model
. Just like we explained above, all mutations get passed the context object, and a payload you set.
As an example, lets say you want to update the user within the model
called "James"
to a name you pass in your payload. We would then create a mutation
with a name along the lines of "updateUser()"
which would do so. As you can see we decontruct
the context object only to use the model
from it, See example below.
"mutations": {
updateUser({$model}, payload) {
$model.users.forEach((user, index) => {
if(user.name == payload.name) {
$model.users[index].name = payload.newName;
}
});
}
}
// using a 'getter' method in your view
ActiveJS.newController("State_Management", {
el: "#app",
Data() {
return {
inputValue: "John"
}
},
methods: {
updateUser() {
ActiveJS.State.Commit("updateUser", {name: "Fred", newName: this.inputValue});
}
}
})
The actions
property is very similar to the mutations property, but there is one key difference between a mutation method and an action method. All actions are for asynchronous
calls and should NEVER update or change
the model itself. Rather you should call a mutation
once you have the asynchronous
data and pass it as a payload.
For example, say we have a table in a database which conatins all our users
. Now we want to get a user and then insert him/her into our model
. Here is where an action will come into play. Lets call this action getUserFromDB()
, and fetch the user from our database
. Once we get the user, we can call a mutaion
to insert the user we just got back. See example below.
"actions": {
getUserFromDB({Commit}) {
fetch("https://someApi/users")
.then((response) => {
if(response.status != 200) {
console.error("Request failed with a status of : "+response.status);
return;
}
// call mutation to insert user
Commit("insertUser", JSON.parse(response.result));
})
.catch((err) => {
console.error("Request failed : "+err);
})
}
}