Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for LoadingCache-like Map #1361

Closed
2 tasks done
Maaartinus opened this issue Aug 7, 2019 · 13 comments
Closed
2 tasks done

Support for LoadingCache-like Map #1361

Maaartinus opened this issue Aug 7, 2019 · 13 comments

Comments

@Maaartinus
Copy link

Question

  • I've checked documentation and searched for existing issues
  • I tried the spectrum channel, but nobody's home.

I need a map, which on get for an absent key creates, returns and stores a new value. A sort of a loading cache. What I mean: A semi-persistent mapping from keys to values. Values are automatically loaded by the cache, and are stored in the cache until either evicted or manually invalidated somehow removed.

I wonder, if

  • there's a good workaround
  • or there is a way how to allow changing already observed observables
  • or this feature could be implemented in a generally useful way

I'm not repeating here all the details from the spectrum channel, a codesandbox link should do.

@holgersindbaek
Copy link

holgersindbaek commented Aug 11, 2019

I'd love to see a solution for this as well. Do you have a temporary solution?

@Maaartinus
Copy link
Author

@holgersindbaek I'm using both setTimeout (so that the key eventually gets a part of the tree) and volatile (so the entry can be found immediately). In the delayed function I move all entries from my volatile map to the main one.

What doesn't work is calling getRoot in the meantime, but that's something I can avoid for now.

It's a pretty ugly workaround, complicated and far from perfect.

@holgersindbaek
Copy link

@Maaartinus From where do you call setTimeout? I'm trying to call it from my mobx-state-tree view, but I'm getting an error.

@Maaartinus
Copy link
Author

@holgersindbaek

I'm trying to call it from my mobx-state-tree view, but I'm getting an error.

Do be that shy and tell us which one. ;)

I have something like

.views(self => ({
     getOrCreate(key) {
          let value = self.map.get(key)
          if (value) return value
          value = createValueForKey(key)
          myVolatileMap.put(key, value)
          setTimeout(() => self.putEntry(key, value)); // <- the relevant line
     }
}))

The important part is letting an action do the change (assuming we're speaking about the same error).

@holgersindbaek
Copy link

holgersindbaek commented Aug 13, 2019

I think we're speaking about the same error. It's something akin to yours:
[mobx] Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ObservableMap@26.keys().

The above makes sense. And then something like this in the putEntry:

putLog(logID, log) { self.logs.set(logID, log) self.cachedLogs.delete(logID) }

@Maaartinus
Copy link
Author

@holgersindbaek Actually, I move everything from the "cachedLogs" into "logs" in the action as it's a bit simpler and less error-prone.

I guess, the best solution would be an option to temporarily disable the error. Maybe

allowToChangeObservablesAlreadyBeingObserved(() => self.putEntry(key, value))

@holgersindbaek
Copy link

What do you mean by "move"? Could you give an example?

@Maaartinus
Copy link
Author

@holgersindbaek You moved a single element (set and delete), I move them all (set in a loop and clear), that's all.

@holgersindbaek
Copy link

Hmm, ok. Thanks. Funny how you can run into the same problem (almost) at the same time :-).

@xaviergonz
Copy link
Contributor

Well, mobx offers a method you "should" not use called _allowChangesInsideComputed or something similar (can't recall the exact name), but you have to be extra careful with it :)

@xaviergonz
Copy link
Contributor

Also if you use atoms I think they can be both reported as changed and as observed inside computeds

@mbest
Copy link
Contributor

mbest commented Apr 15, 2020

The Mobx function is allowStateChangesInsideComputed (mobxjs/mobx#1706)

@coolsoftwaretyler
Copy link
Collaborator

Hey folks - looks like mobxjs/mobx#1706 probably solved this for @Maaartinus. At the very least, this has been inactive for over three years, so I'm going to close it out.

Thanks for all the help here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants