Accessing model out of load order

AI-generated summary

In the discussion Accessing model out of load order, justin is trying to access the user-topics-list model in the user-private-messages controller, but is running into a timing issue where the model always returns null.

Justin is trying to add a conditional statement to the user/messages template, based on the topics array length in the user-topics-list model. Justin is using the api.modifyClass method to add a showMessagesCTA property to the user-private-messages controller. However, the user-topics-list model is not yet loaded when the user-private-messages controller is initialized.

gdpelican suggested a solution, pointing out that user-private-messages.js.es6 provides a direct reference to the userTopicsList controller, which can be used to lookup the model instead of going through the container. gdpelican also suggested setting a watch on the property() to update the computed property automatically when the userTopicsList changes.

Justin reported back that gdpelican’s suggestions worked successfully, and appreciated the help.

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?

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 }
})

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

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