1
votes

I have the following Ember model for users, which contains a list of permissions:

App.User = DS.Model.extend({
    username: DS.attr(),
    permissions: DS.attr(), //e.g. ['edit', 'read']

    isEditor: function() {
        var perms = this.get('permissions');
        return perms.indexOf('edit') > -1;
    }.property('permissions')
});

I use this, amongst other things, to get a list of editors in a controller (for use in a select). When I load the page, I get this error in the console:

Error: Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.

It happened after adding the isEditor function, and if I comment out the contents of the function it works fine, although obviously the list I'm generating from it is incorrect. But as far as I can see there is nothing wrong with the code.

Edit: I'm using the function in a controller mixin:

App.EditorsMixin = Ember.Mixin.create({
    editors: function() {
        return this.store.filter('user', function(model) {
            return model.get('isEditor');
        });
    }.property()
});

Edit 2: It seems that the problem might be related to the fact that not all store.find('user') promises are fulfilled when editors is called. Adding in a few console.log lines and running it though the debugger, I can see that I need something like this:

    editors: function() {
        this.store.find('user').then(function() {            
            return this.store.filter('user', function(model) {
                return model.get('isEditor');
            });
        });
    }.property()

But I can't figure out how to get a list of editors out of the mess of nested promises.

1
I doubt it's that code at all, probably the template using it, would you mind including that? emberjs.jsbin.com/OxIDiVU/940/editKingpin2k
My full code is way to complicated to paste into a bin, and of course I now can't get a small example fail! Sometimes I get TypeError: perms is undefined before the other error though. Is there a sensible way to debug this sort of issue? All I can think of is comment out blocks until I find something that makes a difference but that's not really ideal.aquavitae
returning a promise to a computed property is never ideal, because generally you get a computed property, and not a actual record/collection. The example above isn't returning the find promise, so that definitely wouldn't work ;) In your case, if you want users to be found before a particular controller is used, it'd be best to do that in the router on one of the model hooks (beforeModel, model, afterModel). All of those hooks will block if a promise is returned to them until it's complete. I still wouldn't recommend that. I'd try and fix the underlying problem.Kingpin2k
Commenting out seems like the simplest way to find the issue.Kingpin2k

1 Answers

0
votes

I found the answer, and I was on totally the wrong track. It was simply that the filter function is run every time a record is changed, and some of those times are before all fields are populated. Once that bombs out, the rest follows. So the solution was just to check if perms is defined before using it:

App.User = DS.Model.extend({
    username: DS.attr(),
    permissions: DS.attr(), //e.g. ['edit', 'read']

    isEditor: function() {
        var perms = this.get('permissions');
        if (perms)
            return perms.indexOf('edit') > -1;
        else
            return false;
    }.property('permissions')
});

The somewhat cryptic errors from ember didn't help, but once I started to focus on the TypeError is became a lot clearer.