1
votes

I'm getting two errors with the code I have below. I'm not sure how to go about fixing it. It looks like #each is looking for a promise to be returned rather then a model or an array. Am I right? If yes, how can I have it to take an array or a model? Thanks.

Error 1. Assertion failed: The value that #each loops over must be an Array. You passed [object Object] ember.js:3231

Error 2. Uncaught TypeError: Object [object Object] has no method 'addArrayObserver'

Controller

var StudentBooksController = Ember.Controller.extend({
    needs: ['application','request'],

    selectedBooks: function() {
        //return an array here such as [1, 3, 5, 7]
    }.property(),
    studentList: function() {
        return this.store.find('student');
    }.property(),
    filteredStudentBooks: function() {
        var self = this;

        // I tried "return []" here and no error on the console.

        return self.get('studentList').then(function (students){           
            // I tried "return []" here and it still gave me the same error on console.

            return self.get('selectedBooks').then(function(sb){
                var aList = students.get('content');
                aList.forEach(function(al){
                    al.set('hasAccess', _.contains(sb, sb.get('id') ));
                    console.log(_.contains(sb, sb.get('id') ));
                });

                return aList;
            });
        })
    }.property('selectedBooks','studentList')
});

export default StudentBooksController;

Route

//----- Nothing in the Route file ---

Template

    {{#each filteredStudentBooks}}
        // do something here such as printing the name
        {{name}}
        {{#if hasAccess}}
            User has access.
        {{else}}
            User doesn't have access.
        {{/if}}
    {{/each}}

SOLUTION

With @kingpin2k's help, here is the solution I ended up with.

    filteredStudentBooks: function() {
    var self = this, 
        resp = [];           

    self.get('studentList').then(function (students){           
        // I tried "return []" here and it still gave me the same error on console.

        self.get('selectedBooks').then(function(sb){
            var aList = students.get('content');

            var sortedStudentList = aList.sortBy('name');
            aList = sortedStudentList ;

            aList.forEach(function(al){
                al.set('hasAccess', _.contains(sb, sb.get('id') ));
                console.log(_.contains(sb, sb.get('id') ));
                resp.pushObject(al);
            });                              

        });
    })
    return resp;
}.property('selectedBooks.[]','studentList.[]')
2

2 Answers

2
votes

You're returning a promise and not an array, additionally you probably should be watching the array's changing instead of just the properties.

filteredStudentBooks: function() {
    var self = this, 
        resp = [];


    self.get('studentList').then(function (students){           
        // I tried "return []" here and it still gave me the same error on console.

        self.get('selectedBooks').then(function(sb){
            var aList = students.get('content');

            aList.forEach(function(al){
                al.set('hasAccess', _.contains(sb, sb.get('id') ));
                console.log(_.contains(sb, sb.get('id') ));
            });

            resp.pushObjects(aList.sortBy('name').toArray());
        });
    })
    return resp;
}.property('selectedBooks.[]','studentList.[]')
0
votes

Here is the working solution for my question. @kingpin2k gets the credit for helping most of it. I modified the code to get the sorting and the output to return to the template.

filteredStudentBooks: function() {
    var self = this, 
        resp = [];           

    self.get('studentList').then(function (students){           
        // I tried "return []" here and it still gave me the same error on console.

        self.get('selectedBooks').then(function(sb){
            var aList = students.get('content');

            var sortedStudentList = aList.sortBy('name');
            aList = sortedStudentList ;

            aList.forEach(function(al){
                al.set('hasAccess', _.contains(sb, sb.get('id') ));
                console.log(_.contains(sb, sb.get('id') ));
                resp.pushObject(al);
            });                              

        });
    })
    return resp;
}.property('selectedBooks.[]','studentList.[]')