-1

I have some trouble with my Ember.js model/controller.

My code generates this error:

Uncaught TypeError: this.get(...).toArray is not a function(…)

I have a structure like this:

router.js

Router.map(function() {

  this.route('search', function() {
    this.route('detail', { path: '/:search_id' });
    this.route('ranks', { path: '/:search_id/ranks' });
    this.route('tweets', { path: '/:search_id/tweets' });
  });
});

export default Router;

route/search.js

import Ember from 'ember';

export default Ember.Route.extend({
});

route/search/rank.js

export default Ember.Route.extend({

    model(params) {
        return this.get('store').findRecord('search', params.search_id);
    },

    setupController: function(controller, model) {
        controller.set('model', model);
    }
});

app/models/rank.js

export default DS.Model.extend({
    date: DS.attr(),
    tag: DS.attr('string'),
    rank: DS.attr('number'),
    freq: DS.attr('number'),

    search: DS.belongsTo('search')
});

app/models/search.js

export default DS.Model.extend({
    uniqueid: DS.attr('string'),
    idate: DS.attr('date'),
    fdate: DS.attr('date'),
    keywords: DS.attr(),

    ranks: DS.hasMany('rank')
});

app/controllers/search.js

export default Ember.Controller.extend({
});

app/controllers/search/rank.js

export default Ember.Controller.extend({

    mydata: Ember.computed('model', function() {

       this.get('model').forEach(function(item) {
          console.log(item);
       });
    });
});
1
  • What I want to do is loop the ranks data, how can I get this? This is my JSON: {"searches":[{"id":90,"uniqueid":"search_all","idate":"2016-‌​12-01","fdate":"2016‌​-12-10","keywords":"‌​"}],"ranks":[{"id":1‌​,"rank":1,"tag":"ref‌​erendum","date":"201‌​6-12-05","freq":609,‌​"search":"90"},{"id"‌​:2,"rank":1,"tag":"r‌​eferendum","date":"2‌​016-12-06","freq":14‌​87,"search":"90"},{"‌​id":3,"rank":1,"tag"‌​:"referendum","date"‌​:"2016-12-04","freq"‌​:242,"search":"90"},‌​{"id":4,"rank":1,"ta‌​g":"referendum","dat‌​e":"2016-12-07","fre‌​q":191,"search":"90"‌​}]} Commented Dec 7, 2016 at 12:08

2 Answers 2

1

You're not alone in struggling with this, as I've been seeing a large number of questions recently that illustrate a point about ember-data that I think is being missed.

You call this.store.findRecord('search', params.search_id) which then your api returns the following JSON as per your comment, with 1 search object and 4 rank

{
  "searches":[
    { "id":90,"uniqueid":"search_all","idate":"2016-‌​12-01","fdate":"2016‌​-12-10","keywords":"‌​"}
  ], "ranks":[
    {"id":1‌​,"rank":1,"tag":"ref‌​erendum","date":"201‌​6-12-05","freq":609,‌​"search":"90"},
    {"id"‌​:2,"rank":1,"tag":"r‌​eferendum","date":"2‌​016-12-06","freq":14‌​87,"search":"90"},
    {"‌​id":3,"rank":1,"tag"‌​:"referendum","date"‌​:"2016-12-04","freq"‌​:242,"search":"90"},‌​
    {"id":4,"rank":1,"ta‌​g":"referendum","dat‌​e":"2016-12-07","fre‌​q":191,"search":"90"‌​}
  ]
}

Now if you had done an ajax request, this whole json blob would be available to you. However, because this was an ember data request, not a plain ajax request, you will ONLY get back the single instance of search that you queried for.

This isn't a problem though, because that search object that is returned has a link to rank items that you also got. You can call search.get('ranks') and get all of the loaded ranks.

Solution:

The solution I propose is to gather the ranks that you want in the model and pass them along to your controller. That way, if you want to load them independently of the search, it will work

route/search/rank.js

export default Ember.Route.extend({
  model(params) {
    return this.get('store').findRecord('search', params.search_id).then((search) => {
      // Find record only returns the search object. However, that search object has easy
      // access to all of the previously retrieved rank objects
      return Ember.RSVP.hash({
        search: search,
        ranks: search.get('ranks') // <= key difference here
      });
    });
  },

  setupController: function(controller, model) {
    controller.set('search', model.search);
    controller.set('myRanks', model.ranks);
  }
});

app/controllers/search/rank.js

export default Ember.Controller.extend({
  // ranks are available to you here as myRanks
});

app/views/search/rank/index.hbs

{{#each myRanks as |rank|}}
  <h1>{{rank.rank}}</h1>
{{/each}}
Sign up to request clarification or add additional context in comments.

Comments

0

findRecord return Promise and it will be resolved to a single record. so you can't use forEach for a single record.
You can directly access the properties available inside model, like the below this.get('model.tag') to get tag attribute value.

2 Comments

Thank you so much for your reply. What I want to do is loop the ranks data, how can I get this? This is my JSON: {"searches":[{"id":90,"uniqueid":"search_all","idate":"2016-12-01","fdate":"2016-12-10","keywords":""}],"ranks":[{"id":1,"rank":1,"tag":"referendum","date":"2016-12-05","freq":609,"search":"90"},{"id":2,"rank":1,"tag":"referendum","date":"2016-12-06","freq":1487,"search":"90"},{"id":3,"rank":1,"tag":"referendum","date":"2016-12-04","freq":242,"search":"90"},{"id":4,"rank":1,"tag":"referendum","date":"2016-12-07","freq":191,"search":"90"}]}
You can get ranks as just like other properties this.get('mode').get('rank')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.