0
votes

I am using Ember 1.13.9 an Ember-data 1.13.11 and struggling to have Ember Data do what I would like. As an example, I have a model called "goal" and a

goals: Ember.on('init', Ember.computed(function() {
  const {store} = this.getProperties('store');
  return store.findAll('goal');
})),

When this runs it does query the database and put the appropriate records into the store BUT getting them out of the store is my problem. I would have thought that once the Promise resolved that I'd be able to iterate over the array of results. Using the inspector I can see that at clients.goals.content.content (where clients is the name of the server I see this from the inspector:

enter image description here

First of all this is pretty deep into the structure. I was hoping Ember's "get" would allow me to simply say something like data.get('content.0.id') but this just comes back as undefined. Second of all the crazy structure continues in that each of these listed objects are InternalModel objects which only have the following structure to them:

enter image description here

Note that:

  • there are two InternalModels, that is the right number (matches store results)
  • the id property is available here
  • there is an internal property called _data which has the other attributes of the record

Ok so in a completely hacky way I could pull out what I need but surely I shouldn't be writing code like:

_goals: Ember.on('init', function() {
  const {store} = this.getProperties('store');
  store.findAll('goal').then(data => {
    let result = [];
    data.forEach(item => {
      let record = item.get('data'); // this gets what's in _data apparently
      record.id = item.get('id');
      result.push(record);
    }
    this.set('goals', result);
}),

Yuck. What am I missing?

1
Omg, data is collection of models, why do you create another collection which is exactly the same?Daniel Kmak
I'm sure what I'm doing is wrong, hence the question, but I am not creating another collection which is exactly the same ... the 'data' property which I set once the promise is resolved is a working array of records but terribly ugly in its extraction.ken
Why do you access data property when you have all attributes directly in record? It's unclear for me. What is so special in using goals that you need to create another array? Where do you struggle with using that? I think it's missing part of question.Daniel Kmak
when I execute let record = item.get('data'); I gain access to that attributes but not the idken
recordId = item.get('id'); Where's the problem?Daniel Kmak

1 Answers

1
votes

If you need to convert Ember model to plain object you can use Model.serialize or Model.toJSON methods.

Update:

If you need to not just extract the data from models but to access fetched models via computed property, there are several ways to implement it.

1) Synchronous property (collection):

Controller:

import Ember from 'ember'
export default Ember.Controller.extend({
    goals: [],

    someProperty: Ember.computed('goals.@each', function () {
        var goals = this.get('goals');
        goals.forEach(goal => {
            console.log( goal.get('someProperty') );
        });
    })
});

Route:

import Ember from 'ember'
export default Ember.Route.extend({
    setupController: function (controller, model) {
        this._super(controller, model);
        this.store.findAll('goal').then(goals => {
            controller.set('goals', goals);
        });
    }
});

Template:

{{#each goals as |goal|}}
    {{log goal}}
{{/each}}

2) Asynchronous property (promise):

Controller:

import Ember from 'ember'
export default Ember.Controller.extend({
    goals: Ember.computed(function () {
        var storeGoals = this.store.peekAll('goal') || [];
        if (storeGoals.length) {
            return RSVP.resolve(storeGoals);
        } else {
            return this.store.findAll('goal')
        }
    }),

    someProperty: Ember.computed('goals.@each', function () {
        var goals = this.get('goals').then(resolvedGoals => {
            resolvedGoals.forEach(goal => {
                console.log( goal.get('someProperty') );
            });
        });
    })
});

Template:

{{#each goals as |goal|}}
    {{log goal}}
{{/each}}