rendrjs / rendr

Render your Backbone.js apps on the client and the server, using Node.js.
MIT License
4.09k stars 312 forks source link

error after `collection.fetch` because the cache isn't updated #471

Open wvengen opened 9 years ago

wvengen commented 9 years ago

I have a situation where the CollectionStore doesn't seem to be updated.

In a search box, I'm updating the search results in-place as follows:

module.exports = BaseView.extend({
  'events': {
    'change .search-input': 'onSearch',
    'keyup .search-input':  'onSearchTyped'
  },

  getTemplateData: function() {
    data.collection = this.collection;
  },

  onSearchTyped: _.debounce(function() {
    this.onSearch();
  }, 1200),

  onSearch: function() {
    var params = { q: this.$el.find('.search-input').val() };
    this.collection.fetch({
      data: params,
      reset: true,
      success: function(collection, response, options) {
        var url = '/foobars?' + this.$el.find('form').serialize();
        this.app.router.navigate(url);
        this.render();
      }
    });
  }
});

When text is entered in the search input, the new collection is fetched and the view's collection is updated. However, at some point an exception is thrown:

Error: Collection of type "Foobars" not found for params: {q: "foo"}

Debugging revealed that the fetch was not (yet?) stored in the collection store's cache. When adding this line at the top of the success function, it all works:

this.app.fetcher.collectionStore.set(collection, params);

It seems odd that I need to add something to the cache manually here. Is this a bug, or am I doing something that really isn't intended?

pjanuario commented 9 years ago

I not sure but i think that is because you aren't using application fetcher this.app.fetch(spec, callback).

http://rendrjs.github.io/app/#fetch

saponifi3d commented 9 years ago

Yeah, the problem is the collection.fetch with new params causes some weird stuff to happen to the store since everything is an instance in the store and that the key of a collection is based on the params. I thought it was updating the collections instance to use the new params and then update according to that - though.. I can take a look to see if there is a bug around that code too.

wvengen commented 9 years ago

Thanks, I understand. Ideally, this would be either mentioned in the docs as something inherent in the design, or marked as a bug. I'm afraid I wouldn't be of that much help there. (Feel free to close the issue as not relevant enough, or keep it around as something needing attention.) Thanks for the response!

pjanuario commented 9 years ago

@wvengen I agree with you. When I started with rendr I felt a little bit of that also. Since rendr is just an extension to backbone, the first that come to mind was to use it as a regular backbone model and collection.

@saponifi3d probably overriding collection fetch to use collection.app,fetch would probably avoid this problems. What do you think of it?

crwang commented 9 years ago

@pjanuario I like the idea of someone making the collection.fetch work the way that people would expect. That being said, I'm not sure it's a well-defined behavior because it would be adding caching and we would need some sort of options to bypass caching, since it's good to have but sometimes you don't want it.

@wvengen thanks for sharing your solution. I noticed that there is still a gap in that there is no ability to read from the cache in your fetch call. So, even though the data is stored in the collection store, if you call fetch, it'll still hit the API instead of returning the data stored in the collection store.