Feb. 4, 2022
Response to https://gitter.im/jdubray/sam?at=61fd970e1fe6ba5a970c6dbd.
This is close to JavaScript with some pseudo-code steps to illustrate the click -> loadData (& setStatus) -> model update -> state update -> view render
loop.
<button> onclick: Action({ action: "loadRemoteData" });
loadRemoteData() {
// propose new status
Model({ step: "status", value: "loading" });
// Make asynchronous request
fetch(url)
.then(res => res.json())
.then(json => json.results)
.then(results => {
// Pass results to model.
Model({ step: "update", value: results })
});
}
identifies the acceptor or step function and passes the value.
function Model({ step, value }) {
// step/acceptor functions can be members of Model or private members of internal model API.
Model[step](value);
}
The model's step/acceptor function(s) can guard against same step+value combinations.
function status(value) {
/*
So, if the call to Model({ step: "status", value: "loading" }) does not change
the model's status (i.e., it's already "loading"), then the model can just return
at this point and not notify the State.
*/
if (model.status.value === value) {
return;
}
// Otherwise go ahead and update...
model.status.value = value;
State(model);
}
As for updating the model data, you can mutate it all at once (or run it through normalizing, santizing, error-checking, etc.) and set the status directly.
function update(value) {
model = Object.assign(model, { data: value }, { status: "done" });
State(model);
}