Search code examples
javascriptember.jsember-dataember-controllers

Ember controller not refreshing template after setting property in promise


I might be doing this horribly wrong, but here goes: I am getting the user from the server, and once it is resolved, I am trying to render the user's name to the page. The login form is actually a popup window based on this: http://www.sociallipstick.com/?p=86

Unfortunately, the template doesn't change at all when I set userLoggedIn to true. Am I doing something wrong?

App.UserController = Ember.Controller.extend({
    userLoggedIn: false,
    actions: {
        displayLoginForm: function () {
            //displays a login form
        },
        recieveLogin: function (authResult) {
            //hides login form
            var userPromise = this.store.find('user', authResult); // successfully gets user from server (as far as I can tell)
            var self = this;
            userPromise.then(function (user) {
                self.set('model', user);
                self.set('userLoggedIn', true);
            });
        }
    }
});
<li class="navbar-form">
    {{#if userLoggedIn}}
        <a href="#" class="dropdown-toggle" data-toggle="dropdown"><b class="caret"></b></a>
        <ul class="dropdown-menu">
            <li><a href="#">My quizzes</a></li>
            <li><a href="#">My scores</a></li>
            <li><a href="#">Settings</a></li>
            <li class="divider"></li>
            <li><a href="#">Logout</a></li>
        </ul>
    {{else}}
        <button class="btn btn-default" {{action 'displayLoginForm'}}>Login</button>
    {{/if}}
</li>

Solution

  • This bug was actually caused by a totally different issue than I thought. The callback from the login script used the [hacky] line to get the controller from a popup outside of Ember:

    window.opener.App.__container__.lookup('controller:User').send('recieveLogin', 'USERIDHERE');
    

    Unfortunately, this was actually getting a different instance of the controller which was doing nothing...

    So, I modified the controller like so:

    App.UserController = Ember.Controller.extend({
        userLoggedIn: false,
        actions: {
            displayLoginForm: function () {
                //displays a login form
                /******** THIS IS THE IMPORTANT LINE ********/
                App.UserController.callback = this;
                /******** THAT WAS THE IMPORTANT LINE ********/
            },
            recieveLogin: function (authResult) {
                //hides login form
                var userPromise = this.store.find('user', authResult); // successfully gets user from server (as far as I can tell)
                var self = this;
                userPromise.then(function (user) {
                    self.set('model', user);
                    self.set('userLoggedIn', true);
                });
            }
        }
    });
    

    And then I used the marginally less hacky line on the page:

    window.opener.App.UserController.callback.send('recieveLogin', 'USERIDHERE');