Search code examples
javascriptember.jsfirebasemodal-dialogemberfire

EmberJS + EmberFire: How to display/hide modal based on the number of users logged to website


I am currently using EmberJS 2.6 and EmberFire to build a real time game. I want to display a modal that says 'Waiting for Opponents' when there is only one user in the website and hidden when there are 2.

Currently, I am able to add users to Firebase when they access the website and remove them when they close their browser window. The problem I'm having is that the modal shows up when there is one user in the website, but doesn't disappear when the second connects.

For debugging purposes, I tried adding {{isShowingModal}} to the my-modal.hbs file below. If I open the website on one tab (i.e one user), 'true' gets displayed. If I open the website on a second tab (i.e second user), I see 'true' 'false'. Why doesn't the ember template simply update the value of the isShowingModal property (instead of adding it again to the view)?

Any ideas on how to fix this issue and show the modals correctly? See my code below. Thanks!!!

// app/templates/index.hbs

{{#each users as |user index|}}
    {{my-modal userIndex=index}}
{{/each}}

{{outlet}}

// app/templates/components/my-modal.hbs

{{#if isShowingModal}}
    {{#modal-dialog close="closeModal"
                    translucentOverlay=true}}

        <div class="modal">
            <div id="waitingMessage">
                <h1>Waiting for Opponent</h1>
                <img src="assets/images/loading-icon.gif">
            </div>
        </div>
    {{/modal-dialog}}
{{/if}}

{{yield}}

// app/components/my-modal.js

import Ember from 'ember';

export default Ember.Component.extend({

    userArr: Ember.ArrayProxy.create({content: []}),
    isShowingModal: null,

    init() {
        this._super(...arguments);
        var self = this;

        this.get('userArr').pushObject(self.attrs.userIndex.value);

        if(this.get('userArr').content.length < 2) {
            this.set('isShowingModal', true);
        } else {
            this.set('isShowingModal', false);
        }

    },

    willDestroyElement() {
        this._super(...arguments);
        var self = this;

        this.get('userArr').popObject(self.attrs.userIndex.value);

        if(this.get('userArr').content.length < 2) {
            this.set('isShowingModal', true);
        }
    }

});

Solution

  • The reason that ember is adding the showModal instead of updating it is because it's inside the component which is inside the list.

    What I would recommend is to move the code to show/hide the modal out of the component and into the controller. Like this:

    //app/controllers/index.js
    import Ember from 'ember';
    
    export default Ember.Controller.extend({
      // Other code
      shouldShowModal: Ember.computed('users.[]', function() {
        if (this.get('users.length') < 2) { return false; }
        return true;
      })
    })
    

    then in your template

    //app/templates/index.hbs
    ...
    {{#if shouldShowModal}}
      ... code to show modal
    {{/if}}
    ....
    

    That way you have access to the length of the list of users and can control showing the modal based off of that.