2
votes

Using Ember 1.11 I have a search function working that will run a parameterized find(), but then I want to be able to go back to the state before the find, with only the records that were there before. In my app, this is the records the API returns with no query parameters.

My route's model hook

  model: function(params) {
    if (params.q) {
      return this.store.find('project', params);
    } else {
      return this.store.findAll('project');
    }
  }

However, what currently happens is when the user goes back (by using an action that clears the query parameter):

backToMyProjects: function() {
  this.set('q', null);
}

(this jsbin is an example from @lolmaus that helped me get that working) then all the records are still in the store, so when it does findAll(), it gets back both sets of records, when what I really want is for it to clear out the store, then use the records from the findAll(). The server API call is happening correctly in both places, it's just that the model hook is called with no params after it's been called once with params, then the store has extra records in it.

So then I tried adding this.store.unloadAll('project') but then I get an error after going from a parameterized query, back to one without parameters.

Updated model hook

model: function(params) {
  if (params.q) {
    return this.store.find('project', params);
  } else {
    this.store.unloadAll('project');
    return this.store.findAll('project');
  }
},
//this isn't new, just forgot to put it earlier. when the query param is modified, the model hook is called again (as I understand it).
queryParams: {
  q: {
    refreshModel: true
  } 
}

Error message

Error while processing route: projects Assertion Failed: calling set on destroyed object Error: Assertion Failed: calling set on destroyed object
    at new Error (native)
    at Error.EmberError (http://localhost:4200/assets/vendor.js:22615:21)
    at Object.Ember.default.assert (http://localhost:4200/assets/vendor.js:15716:13)
    at Object.set (http://localhost:4200/assets/vendor.js:26367:22)
    at exports.default.mixin.Mixin.create.set (http://localhost:4200/assets/vendor.js:41034:20)
    at Ember.Object.extend.flushCanonical (http://localhost:4200/assets/vendor.js:69680:14)
    at ember$data$lib$system$relationships$state$has_many$$ManyRelationship.flushCanonical (http://localhost:4200/assets/vendor.js:71436:22)
    at Queue.invoke (http://localhost:4200/assets/vendor.js:11425:18)
    at Object.Queue.flush (http://localhost:4200/assets/vendor.js:11490:13)
    at Object.DeferredActionQueues.flush (http://localhost:4200/assets/vendor.js:11295:19)
1
this.store.unloadAll is correct. Please post the precise error message and the code you tried.Gaurav
I tried model() { this.store.unloadAll('book'); return this.store.findAll('book'); } in one of my apps and didn't get any runtime error. As Gaurav said please post the exact error messageFrank Treacy
Added the error message. This doesn't occur on initial load of the page (route = /projects), but it does when going from a route with the query back to the non-query route, using the controller action backToMyProjects.redOctober13
What version of ember-data? As of 1.13, findAll accepts reload: truesteveax

1 Answers

1
votes

In the else condition, use find() again instead of findAll() which gets everything from the store:

return this.store.find('project');

UPDATE: never mind, in 1.11 and up, this will call findAll() under the covers anyway. Not sure how to force it to not use the store.

so far, I have wrapped the unloadAll() in an Ember.run, and it appears to work, but I'm not sure why this is necessary:

  model: function(params) {
    if (params.q) {
      return this.store.find('project', params);
    } else {
      var _this = this;
      Ember.run(function() {
        _this.store.unloadAll('project');
      });
      return this.store.find('project');
    }
  }