Accessing model out of load order


(Justin DiRose) #1

Hey all, I’m trying to work through an issue in the user-private-messages controller in a theme.

Here’s what I’m trying to do.

  • In the user/messages template, add content if there are fewer than 5 private messages in the list.
    Example:
{{#if showMessagesCTA}}
   <p>Hey here I am!</p>
{{/if}}
  • I’m modifying the user-private-messages controller to add the showMessagesCTA method, as this appears where the template pulls logic from. The data I need is in the user-topics-list model, in particular the topics array.
    Example:
api.modifyClass("controller:user-private-messages", {
    showMessagesCTA: function() {
        let userTopicsListModel = api.container.lookup("controller:user-topics-list").get('model');
        if (userTopicsListModel && userTopicsListModel.topics){
             return userTopicsListModel.topics.length() < 5;
        } else {
             return false;
        }
    }.property()
});

The problem I’m running into is the model always returns null. I’m guessing this is a timing issue because the user-private-messages controller loads prior to user-topic-list. When I log just the user-topics-list controller, it shows up but is greyed out. Clicking into it shows all the data, but it’s clearly not accessible in the app.

Is there a better way to approach accessing this data I’m not accounting for?


(James Kiesel) #2

Looks like user-private-messages.js.es6 provides a direct reference to the userTopicsList controller, so you probably want to use that to lookup rather than going through the container.

# user-private-messages.js.es6#6
userTopicsList: Ember.inject.controller("user-topics-list"),

This also means that you can set a watch on the property() so that the computed property updates automatically when the userTopicsList changes

api.modifyClass("controller:user-private-messages", {
  showMessagesCTA() {
    return this.get("userTopicsList.model.topics.length") < 5
  }.property("userTopicsList.model.topics.length")
})

Bonus points, I believe property() passes its arguments into the method (and if not, using the @on decorator does), so you could end up with something like

api.modifyClass("controller:user-private-messages", {
  @on("userTopicsList.model.topics.length")
  showMessagesCTA(length) { return length < 5 }
})

(Justin DiRose) #3

These are some good ideas - I’ll give them a go and report back. Thanks sir!


(Justin DiRose) #4

@gdpelican I really appreciate your help with this – your suggestions worked like a charm!