Netflix / falcor

A JavaScript library for efficient data fetching
http://netflix.github.io/falcor
Apache License 2.0
10.48k stars 446 forks source link

decorating model resulting in setCache being undefined #988

Closed JulietAdams closed 3 years ago

JulietAdams commented 3 years ago

I am attempting to do some manual cache invalidation but am finding that when I try to call model.setCache(...) it throws saying the method is undefined.

My model is defined as follows:

export const model = new Model({
  source: HTTPDataSource('/api/model.json'),
  onChange: graphChange,
})
  .batch()
  .boxValues()
  .treatErrorsAsValues()

I already did some digging around in Falcor's source code and it seems that the issue is a side effect of my use of boxValues and treatErrorsAsValues. Both of these methods use model._clone which does the following when creating a clone

clone.setCache = void 0;

To me this seems intentional, and assuming my intuition is correct, what is the best way to proceed here? I'm also rather curious as to why setCache is set to undefined when creating a clone?

On my own I did find that the following seems to work but I'm not sure if there are side effects/issues that will come up that I am not thinking/aware of, and I also wanted to see what your recommended approach is.

const baseModel = new Model({
  source: HTTPDataSource('/api/model.json'),
  onChange: graphChange as () => void,
})

export const model = baseModel
  .batch()
  .boxValues()
  .treatErrorsAsValues()

const invalidate = (...) => baseModel.setCache(...) // this is an oversimplification of the method obviously
jcranendonk commented 3 years ago

The removal on setCache on clones is indeed intentional; it was a workaround to avoid cache tearing in clones in certain scenarios involving Model dereferencing. It's complicated, and the exact issue is lost to the mists of time, but it appears to be a rare occurrence.

There are two ways you can still use setCache, however: