0
votes

I have a fairly simple ember-cli application (using Ember 2.2 & Ember Data 2.2.1) with a single model named 'scenario'. I have a route name 'scenarios' that lists all the scenarios. All that works fine. In my application template, I have a nav bar with a button that triggers an action to delete all scenarios. My application controller code looks like this for that action:

this.store.findAll('scenario').then(function(recs){
    recs.forEach (function (rec) {
        rec.destroyRecord();
        });
    }, console.log ('findAll Scenario failed'));

When I run this code, the console.log always prints, indicating that the promise returned didn't fulfill. But there are clearly records in the scenario model. I can see them on the screen in the "scenarios" route, and also in Ember inspector. Why is this 'findAll' not fulfilling?

One other thing to note: when this code is run, Ember Inspector actually shows the same records I'm trying to delete been added. (e.g., if I have 2 scenarios with ids 23 & 24 respectively, initially I see two rows in Ember Inspector as expected. After this code runs, I see 4 rows, two with id 23 and two with id 24). But the 'MODEL TYPES" column in Ember inspector still says scenario(2), indicating only 2 records. Anyone know what's going on?

Update (more information)

If I do an unload as follows in lieu of the 'findAll' code snippet:

this.store.unload('scenario');

I still see the rows in Ember Inspector, but the "MODEL TYPE" column actually shows 'scenario(0)', and the records no longer show in the 'scenarios' route, which is good. Of course when I do a refresh, the records come back since the server was never notified to delete these records. For some reason, Running the above 'unload' statement after the 'findAll' code snippet has no effect.

Update (more info)

Also tried:

  this.store.findAll('scenario').then(function(recs){
    recs.forEach (function (rec) {
        Ember.run.once (this, function() {
        rec.destroyRecord();
        });
        });
    }, console.log ('findAll Scenario failed'));

Same error.

More Update

Oversight on my part on the console.log call. I did as Peter suggested and modified my code to the following:

 this.store.findAll('scenario').then(function(recs){
    recs.forEach (function (rec) {
        Ember.run.once (this, function() {
        rec.destroyRecord();
        console.log ('found');
        });
        });
    }, function() {
        console.log ('findAll Scenario failed');
    }
);

This code verified the findAll did find the records. But the original problem persists only with slightly different symtoms. I added two records, then ran the above code. Instead of deleting those two records, Ember added two rows as before; "MODEL TYPE" still showed scenario(2). But if I ran this same code again, "MODEL TYPE" went to scenario(0), and the records no longer showed in the scenarios route. But the 4 rows remained in Ember inspector.

I think there's a bug in Ember Data somewhere. But it's really hard to pin it down to report.

2

2 Answers

1
votes

You are using console.log statement directly where you should have a callback function. Hence findAll Scenario failed will always execute.

Try this:

this.store.findAll('scenario').then(
    function(recs){
        recs.forEach (function (rec) {
            Ember.run.once (this, function() {
                rec.destroyRecord();
            });
        });
    }, function () { // <-- callback
        console.log ('findAll Scenario failed');
    }
);
1
votes

A promise's then takes two functions as its parameters - one function that will get executed if it is successful, and another function that is executed if it fails. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

As Petter showed, you need to put your console.log inside of a function. What you could also do is declare two functions on your controller, for instance didFindScenarios and didNotFindScenarios, and pass those into the then function, though it is important to call .bind(this) on them if you want to make sure they have the correct this reference to the application controller.

For example, in your application controller:

didFindScenarios: function(recs){
  recs.forEach (function (rec) {
    Ember.run.once (this, function() {
        rec.destroyRecord();
    });
  });
  this.set('isProcessing', false); //we have the 'this' that refers to this application controller since we called `.bind(this)` on this function
},

didNotFindScenarios: function(err){
  console.log ('findAll Scenario failed. Here is the error: ' + err);
  this.set('isProcessing', false);
},

actions: {
  deleteAllScenarios: function(){
      this.set('isProcessing', true); //just an example using 'this'
      this.store.findAll('scenario').then(this.didFindScenarios.bind(this), this.didNotFindScenarios.bind(this));
  },
}