Methods

โ—๏ธinfo

Here are useful methods of the State Class listed.

setKey()#

Assigns a new Key/Name to our State.

MY_STATE.setKey("newKey");
MY_STATE.key; // Returns 'newKey'

โ“ Why a Key#

We recommended giving each State an unique Key. I promise you, it has only advantages.

  • helps us during debug sessions
  • makes it easier to identify a State
  • no need for separate persist Key

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
valuestring | number | undefinedundefinedNew Key/Name of StateYes

๐Ÿ“„ Return#

Returns the State it was called on.




set()#

Allows us to mutate the current value of our State.

MY_STATE.set("myNewValue");
MY_STATE.value; // Returns 'myNewValue'

Under the hood it ingests the State into the runtime, which applies our new defined Value to the State and ensures that each Component which has bound the State to itself rerender.

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
valueValueType = anyundefinedNew State ValueYes
configStateIngestConfig{}ConfigurationNo

๐Ÿ“„ Return#

Returns the State it was called on.




ingest()#

โ—๏ธinfo

This function is manly thought for the internal use.

Ingests our State without any specific value into the runtime. Instead of the passed value, the nextStateValue will be used as the new State Value instead.

MY_STATE.nextStateValue = "frank";
MY_STATE.ingest();
MY_STATE.value; // Returns 'frank'

If our State is a specific extension of the State, like the Computed State, the recomputed value will be used as the nextStateValue instead.

let coolValue = "jeff";
const MY_COMPUTED = App.createComputed(() => coolValue); // Computed Value is 'jeff'
coolValue = "frank";
MY_COMPUTED.value; // Returns 'jeff'
MY_COMPUTED.ingest();
MY_COMPUTED.value; // Returns 'frank'

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
configStateIngestConfig{}ConfigurationNo

๐Ÿ“„ Return#

Returns the State it was called on.




type()#

โ—๏ธinfo

We recommend Typescript Users to use generic types instead of the type function.

const MY_STATE = createState<string>("hi");
MY_STATE.set(1); // Error in editor
MY_STATE.set("bye"); // Success in editor

Forces State to only allow mutations of the provided type. This is different from Typescript as it enforces the type at runtime.

MY_STATE.type(String);
MY_STATE.set(1); // Error at runtime
MY_STATE.set("hi"); // Success at runtime

The type function takes in the JS constructor for that type, possible options are:

Boolean, String, Object, Array, Number

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
typeanyundefinedType that gets applied to the StateNo

๐Ÿ“„ Return#

Returns the State it was called on.




hasCorrectType()#

โ—๏ธinfo

Only useful if we have used the type function to define the type of our State.

Checks if the given value has the correct type at runtime. It compares whether the value has the same type as the type, which was previously defined with help of the type function.

MY_STATE.type(String);
MY_STATE.hasCorrectType("hi"); // Returns 'true'
MY_STATE.hasCorrectType(12); // Returns 'false'

๐Ÿ“„ Return#

boolean




undo()#

Reverses the latest State Value mutation. Be aware that it can only reverses one State change at once, that's why we can't do undo().undo().undo() to get to the State Value from before 3 State changes.

MY_STATE.set("hi"); // State Value is 'hi'
MY_STATE.set("bye"); // State Value is 'bye'
MY_STATE.undo(); // State Value is 'hi'

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
configStateIngestConfig{}ConfigurationNo

๐Ÿ“„ Return#

Returns the State it was called on.




reset()#

Sets the State Value to its initial Value.

const MY_STATE = App.createState("hi"); // State Value is 'hi'
MY_STATE.set("bye"); // State Value is 'bye'
MY_STATE.set("hello"); // State Value is 'hello'
MY_STATE.reset(); //๏ธ State Value is 'hi'

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
configStateIngestConfig{}ConfigurationNo

๐Ÿ“„ Return#

Returns the State it was called on.




patch()#

โ—๏ธinfo

Only relevant for States which have an object as value type.

Merges an object into the current State Value object.

const MY_STATE = App.createState({id: 1, name: "frank"}); // State Value is '{id: 1, name: "frank"}'
MY_STATE.patch({name: "jeff"}); // State Value is '{id: 1, name: "jeff"}'
const MY_STATE_2 = App.createState(1);
MY_STATE.patch({hello: "there"}); // Error

โ“ Deepmerge#

Unfortunately the patch function doesn't support deep merges yet. Currently, the merge only happens at the top-level of our objects. This means, that it doesn't look for deep changes, if it cannot find a particular property, it will add it at the top-level of the object.

const MY_STATE = App.createState({things: { thingOne: true, thingTwo: true }}); // State Value is {things: { thingOne: true, thingTwo: true }}
MY_STATE.patch({ thingOne: false }); // State Value is {things: { thingOne: true, thingTwo: true }, thingOne: false}

If we don't want to add not existing properties to the object, we can set addNewProperties to false.

const MY_STATE = App.createState({things: { thingOne: true, thingTwo: true }}); // State Value is {things: { thingOne: true, thingTwo: true }}
MY_STATE.patch({ thingOne: true }, {addNewProperties: false}); // State Value is {things: { thingOne: true, thingTwo: true }}

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
targetWithChangesObjectundefinedObject that gets merged into the current State ValueYes
configPatchConfig{}ConfigurationNo

๐Ÿ“„ Return#

Returns the State it was called on.




watch()#

Observes our State and calls a callback function on each State Value mutation.

const response = MY_STATE.watch((value, key) => {
console.log(value); // Returns current State Value
console.log(key); // Key of Watcher ("Aj2pB")
});
console.log(response); // "Aj2pB" Random generated Key to idetify the watcher callback

We recommend giving each watcher callback a unique key to properly identify it later.

const something = MY_STATE.watch("myKey", (value) => {
// do something
});
console.log(response); // State Instance it was called on

A proper identification is for instance necessary, to clean up our watcher callback later.

โ“ When should I cleanup#

If we have to use a watcher in component code, it is important to clean up after using it. Because if the component unmounts, and the watcher remains it can cause memory leaks.

MY_STATE.removeWatcher(cleanupKey);

๐Ÿš€ useWatcher#

If you use React, like me and don't want to worry about cleaning up the watcher callback, just use the useWatcher Hook, which automatically takes care of it.

export const MyComponent = () => {
useWatcher(MY_STATE, (value) => {
// do something
})
return <div></div>
}

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
keystring | numberundefinedKey/Name of Watcher CallbackNo
callback(value: ValueType) => voidundefinedCallback Function that gets called on every State Value changeYes

๐Ÿ“„ Return#

Returns the State it was called on, if we pass our own Key. Otherwise, it generates us a random Key and returns this.




removeWatcher()#

Removes watcher callback at specific Key. Such a cleanup is important, after we have no reason to use the watcher callback anymore. For instance after a Component has been unmounted to avoid memory leaks.

MY_STATE.removeWatcher("myKey");

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
keystringundefinedKey/Name of Watcher Callback that gets removedYes

๐Ÿ“„ Return#

Returns the State it was called on.




hasWatcher()#

Looks if a watcher function exists at a certain key.

MY_STATE.watch("myKey", (value) => {
// do something
});
MY_STATE.hasWatcher("myKey"); // Returns 'true'
MY_STATE.hasWatcher("unknownKey"); // Returns 'false'

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
keystringundefinedKey/Name of WatcherYes

๐Ÿ“„ Return#

boolean




onInaugurated()#

Is a watcher function, which destroys itself after the first call.

MY_STATE.onInaugurated((value) => {
// do something
});

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
callback(value: ValueType) => voidundefinedCallback Function that gets called once when the State Value got instantiatedYes

๐Ÿ“„ Return#

Returns the State it was called on.




persist()#

Preserves State Value in the appropriate local storage for the current environment. No matter if Mobile or Web environment as long as we have configured our Storage correctly.

MY_STATE.perist("myPersistKey");

๐Ÿ’ป Web#

I guess the most people persisting something on the web, will use the Local Storage. Luckily AgileTs has already set up it by default, as long as you haven't disabled it.

const App = new Agile({
localStorage: true
})

So there is noting to setup here.

๐Ÿ“ฑ Mobile#

In the mobile environment the Local Storage unfortunately doesn't exist, so we might use the Async Storage. The Async Storage isn't configured by default, so we have to do it on our own.

App.registerStorage(
new Storage({
key: "AsyncStorage",
async: true,
methods: {
get: AsyncStorage.getItem,
set: AsyncStorage.setItem,
remove: AsyncStorage.removeItem,
},
}), {default: true}
);

๐Ÿ”‘ Local Storage Key#

To persist our State, we have two options to provide the persist function the required Storage Key.

  • 1. Assign a unique Key to our State, because if no key was given to the persist function, it tries to use the State Key as Storage Key.
    MY_STATE.key = "myCoolKey";
    MY_STATE.persist(); // Success
  • 2. Pass the Storage Key directly into the persist function.
    MY_STATE.persist("myCoolKey"); // Success

If AgileTs couldn't find any key, it drops an error and doesn't persist the State Value.

MY_STATE.key = undefined;
MY_STATE.persist(); // Error

๐Ÿ“ Multiple Storages#

If our Application for whatever reason has more than one registered Storages that get actively used. We can define with help of the storageKeys in which Storage the persist function stores the State Value.

MY_STATE.persist({
storageKeys: ["myCustomStorage"]
})

By default, it gets stored in the default Storage.

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
keystring | numberundefinedKey/Name of created Persistent (Note: Key required if State has no set Key!)No
configStatePersistentConfig{}ConfigurationNo

๐Ÿ“„ Return#

Returns the State it was called on.




onLoad()#

Gets called whenever our persisted State Value got loaded into the State.

MY_STATE.onLoad((success) => {
console.log(`Value '${MY_STATE.value}' got loaded into the State! Success? ${success}`)
});

For instance this might be useful, to show a loading indicator until the persisted Value got loaded.

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
callback(success: boolean) => voidundefinedCallback Function that gets called once, when the Storage Value got loaded into the StateYes

๐Ÿ“„ Return#

Returns the State it was called on.




copy()#

Creates a fresh copy of the current State Value, without any reference.

const MY_STATE = App.createState([1, 2, 3]);
MY_STATE.copy(); // Returns '[1, 2, 3]' without any reference to the orginal Value

๐Ÿ“„ Return#

Returns a fresh copy of the current State Value(ValueType).




exists()#

Checks if the State exists.

const MY_STATE = App.createState("hi");
MY_STATE.exists; // Returns 'true'

๐Ÿ“„ Return#

boolean




is()#

Checks if the State Value is equal to the provided value. Equivalent to ===.

const MY_STATE = App.createState("hi");
MY_STATE.is("bye"); // Returns 'false'
MY_STATE.is("hi"); // Returns 'true'

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
valueValueType (any)undefinedValue that gets checked if its equals to the State ValueYes

๐Ÿ“„ Return#

boolean




isNot()#

Checks if the State Value isn't equal to the provided value. Equivalent to !==.

const MY_STATE = App.createState("hi");
MY_STATE.isNot("bye"); // Returns 'true'
MY_STATE.isNot("hi"); // Returns 'false'

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
valueValueType (any)undefinedValue that gets checked if its not equals to the State ValueYes

๐Ÿ“„ Return#

boolean




invert()#

โ—๏ธinfo

Only relevant for States which have an boolean as value type.

Inverts current State Value.

const MY_STATE = App.createState(true);
MY_STATE.invert();
MY_STATE.value; // Returns 'false'

๐Ÿ“„ Return#

Returns the State it was called on.




compute()#

Recomputes value on each State change.

const MY_STATE = App.createState("Jeff").compute((value) => `Hello '${value}'`);
MY_STATE.value; // Returns "Hello 'Jeff'"
MY_STATE.set("Frank");
MY_STATE.value; // Returns "Hello 'Frank'"

๐Ÿ‘พ Computed vs compute()#

The compute method is just a simple method to compute our Value and isn't as powerful has the Computed Class. For instance, the compute method doesn't recompute if a dependency mutates.

๐Ÿ“ญ Props#

PropTypeDefaultDescriptionRequired
method(value: ValueType) => ValueTypeundefinedComputed MethodYes

๐Ÿ“„ Return#

Returns the State it was called on.

Last updated on