Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SAM pattern, loose example of pattern to click for data, show "loading" status, request data, handle data response, and update status again.

SAM looping example

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.

View:

<button> onclick: Action({ action: "loadRemoteData" });

Action:

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 })
    });
}

Model

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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment