How to mutate a data object -- ensuring values update

Hi Observablers!

I am working on a proof-of-concept data application, and trying to find a way to mock up a representation of changing a data source (showing, e.g. changes between projecct1 and project1).

I have defined three datasets: original_data (e.g. project1), state_data (current view), and changed_data (e.g. project2).

I have also defined button inputs to load the different datasets, e.g.:

viewof load_state_data = Inputs.button("Load Original Data");

and

write_original_data = {
  if (load_state_data) {
    Object.assign(state_data, original_data);
  }
  state_data;
};

When I click the button, if I go back to ‘state_data’ and click the down arrow icon to explore data, I can see that the values change on click … but not until I interact with the Inspector view. Also, if I show just a value in the dataset, like state_data.name, the representation of that attribute doesn’t ever seem to change.

Any suggestions for how I should adjust my approach?

Notebook is here: Data Mutation - Check / Aaron Kyle Dennis | Observable

I got it. I should have been combining the handling of buttons into one function and returning the data directly:

new_state_data = {
  if (load_original_data) {
    Object.assign(state_data, original_data);
  } else if (load_changed_data) {
    Object.assign(state_data, changed_data);
  }
  return state_data;
}

… I guess I didn’t get it after all :frowning:

When I try to remove the extra write function I created, my function listening to the update button no longer consistently swaps out the data. Here’s a slightly reduced version of the original notebook:

Any tips?

Ok, I think I really got it…

I created a swap data function:

function swap_data(data) {
  mutable state_data = data;
}

Then I invoke this function alongside the respective button, like this:

load_original_data,
swap_data(original_data),
mutable state_data

…and now it works!

… Added another for the change to occur within the button definition so that it doesn’t execute when the notebook loads. I think this finally gets to where it’s meant to be for the reactive environment. :rocket: