Updating mutable inside function

Demo notebook here: https://observablehq.com/@jerryjappinen/mutable-fetch-test

What I want to do

I’m querying a paginated list of users. I want to have all users in one object by ID.

I have a mutable allUsers = ({}) object. Then, in my async fetchUsers I update allUsers once I get a response.

Problem: I get an endless loop of requests when updating mutable allUsers inside fetchUsers. My guess is that it throws off Observable’s change detection and it thinks fetchUsers need to be run every time allUsers is updated.

This has to be dynamic. I do not want to hardcode a variable for every fetch and combine those into allUsers. Order fetching is also important: every time I query the API, any users returned is considered to be the newest version of this object, so it should override a previously included object with the same ID.

Questions

  • Can this be made to work?
  • Is there a more “observable” way of doing this?

I’ve tried to play with workarounds (using yield etc.) but have not been able to get this working.

1 Like

Hi Jerry,

It looks like this is because in the object spread you reference allUsers, which does make the observable runtime consider that cell to be downstream of allUsers and reevaluates the cell when allUsers changes. You can fix this by referencing mutable allUsers instead which removes that reactivity:

mutable allUsers = { ...mutable allUsers, ...responseUsersById }

instead of

mutable allUsers = { ...allUsers, ...responseUsersById }
1 Like

This is indeed it. Still had not quite grasped this with mutable. Thanks for the quick response @duaneatat !

I’ve updated the demo notebook with working code.

1 Like