mobxjs / mobx-state-tree

Full-featured reactive state management without the boilerplate
https://mobx-state-tree.js.org/
MIT License
6.9k stars 639 forks source link

Add safeMap utility (or something like it) #2109

Open coolsoftwaretyler opened 8 months ago

coolsoftwaretyler commented 8 months ago

If you have something like:

const DocumentModel = types.model({
  id: types.identifier,
  text: types.string
})

const DrawerModel = types.model({
  id: types.identifier,
  documents: types.array(types.reference(types.late(() => DocumentModel))),
})

And you load all your Drawers before loading Documents, and you can't guarantee that drawer.documents will end up referring to valid IDs, you'll end up with an error when if you call drawer.documents.map, because we're invoking the reference.

It would be awesome to be able to safely iterate the array in some way with a helper function. Something like this:

const safeMap = (array, success, error) => {
    if (array.length === 0) {
        return;
    }

    const isValid = isValidReference(() => array[0]);
    if (isValid) {
        success(array[0]);
    } else {
        error(array[0]);
    }

    safeMap(array.slice(1), success, error);
}

(This implementation may crash right now, I'm not exactly sure how to get it to work).

Would be nice to offer it as a utility on types.array, and similarly on types.map for things.

This came from a real-world problem using MST to load data from an API where document IDs couldn't be guaranteed to be valid by the time they get loaded.

I don't love expanding the API surface of our already-large API, but this could be helpful. At the very least, maybe we offer a code snippet in the docs to help folks in this scenario.

Happy to see some reproductions, demos, PRs, etc.