Joe B
Joe B

Reputation: 1271

ember.js .find() only works when called 2nd time

Main goal: Using .find() to access a model other than the one available in the current controller -in order to compare data from the current controller's model with a piece of data from a 'foreign' controller's model.

What triggers the comparison: I have a button inside a template with {{ action "isResponse"}}. This template's controller has an isResponse : function() {...}

The problem I have: The action is fired every time I click the button, but App.Answer.find() only returns content after the 2nd click. I'm wondering if this is because the Answer model hasn't loaded, but am unsure how to properly set up an observer for isLoaded in my example (if that is even the issue)

So how come App.Answer.find() returns empty the first time it's called??

App.ChoiceController = Ember.ObjectController.extend({

    chosen: false,

    isResponse: function() {

        // successfully returns what I want from this controller's model
        var questionId = this.get('question.id')

        // gets DS.RecordArray of the model i'd like to compare with
        var answers = App.Answer.find()

        // filter to get a result that matches this.get('question.id')
        var answer = answers.filter(function(ans) {

            // returns all entries that match
            if(ans.get('question.id') == questionId) { return true }

        }, 'answers.isLoaded'); // this observer doesn't seem to hurt or help

        // get the final value I need 
        var choice = answer.mapProperty('choice.id')

        // if choice array is not empty, (should only have 1 element anyways)
        if(!choice) {
            this.set('chosen', choice[0]);

        } else {

            this.set('chosen', false);
        }
    }

})

Here are the models involved. Both include DS.belongsTo attributes

App.Choice = DS.Model.extend({

    "question" : DS.belongsTo('App.Question')

})

App.Answer = DS.Model.extend({

    "question" : DS.belongsTo('App.Question')
    "choice" : DS.belongsTo('App.Choice')    

})

App.Question = DS.Model.extend({

})

EDIT

Here is jsfiddle showing the behavior. Make sure to open your browser console to notice that each button requires 2 clicks for action isResponse to function properly. http://jsfiddle.net/iceking1624/QMBwe/

Upvotes: 1

Views: 389

Answers (1)

intuitivepixel
intuitivepixel

Reputation: 23322

After reading your comment I've retought a solution to your problem and one possible way might be that you can define a AnswerController of type ArrayController (since it's for a collection of answers) and then setup this controller in your ApplicationRoute's setupController hook.

Main goal: Using .find() to access a model other than the one available in the current controller -in order to compare data from the current controller's model with a piece of data from a 'foreign' controller's model.

Later on you can then require access to the AnswerController's data using the needs API with needs:['answers'] from inside whatever controller that needs access to the answers collection, and finally have access to the data with this.get('controllers.answer'). You can find here more info on the needs API.

See here a possible solution that works correctly, displaying the right choice already on the 1st click:

App.AnswerController = Ember.ArrayController.extend({});

App.ApplicationRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    this.controllerFor('answer').set('content', App.Answer.find());
  }
});

App.ChoiceController = Ember.ObjectController.extend({
  needs: ['answer'],
  chosen: false,
  isResponse: function() {

    var questionId = this.get('question.id');

    var answers = this.get('controllers.answer');

    var answer = answers.content.filter(function(ans) {
      if(ans.get('question.id') == questionId) { return true }
    }

    var choice = answer.mapProperty('choice.id');

    if(!choice) {
      this.set('chosen', choice[0]);
    } else {
      this.set('chosen', false);
    }
  }
});

And here a working fiddle.

Hope it helps.

Upvotes: 1

Related Questions