Search code examples
firebasefirebase-realtime-databasevue.jsvuefire

Vue & Firebase class binding


New to both Vue & Firebase here. I'm prototyping an app that has a matrix of buttons that I'd like for all users across devices to be able to see which buttons are "active" by applying a css class to the button when the database has changed. I'm using VueFire to bind the Firebase reference with Vue.

At first I tried something like this but it didn't work and I feel like it's probably not the right way to do it anyway.

HTML

<button v-bind:class='{ "active": buttons['button1'] }'>                
<button v-bind:class='{ "active": buttons['button2'] }'>                
<button v-bind:class='{ "active": buttons['button3'] }'>
<button v-bind:class='{ "active": buttons['button4'] }'>        

Then, I thought I'd be able to use a method to determine if the button is active based on its name but it is not working either.

HTML

<button v-bind:class='{ "active": isBtnActive("button1") }'>                
<button v-bind:class='{ "active": isBtnActive("button2") }'>                
<button v-bind:class='{ "active": isBtnActive("button3") }'>
<button v-bind:class='{ "active": isBtnActive("button4") }'>        

Javascript

var buttonsRef = firebase.database().ref('buttons');

var app = new Vue({ 
    el: '#app',
    data: {
    },
    firebase: {
        buttons: buttonsRef
    },  
    methods: {      
        isBtnActive: function(name) {           
            return buttonsRef.child(name);              
        }
    }
});

Firebase data as JSON

{
    "buttons": {
        "button1": false,
        "button2": false,
        "button3": false,
        "button4": false
    }   
}

What am I missing? I seems like this should be straight forward functionality.


Solution

  • Based on that database structure, this.buttons will look something like this:

    [ { ".value": true, ".key": "button1" }, { ".value": false, ".key": "button2" }, { ".value": false, ".key": "button3" }, { ".value": true, ".key": "button4" } ] 
    

    That being the case, your isBtnActive method should look like this:

    isBtnActive(btn){
      const button = this.buttons.find(b => b[".key"] === btn)
      if (button) return {active: button[".value"]}
      else return {active: false}
    }
    

    Alternatively you could retrieve buttons as an object.

    firebase: {
      buttons: {
        source: buttonsRef,
        asObject: true,
      }
    },
    

    And change your method to

    isBtnActive(btn){
      return { active: this.buttons[btn]}
    }
    

    Or omit the method altogether.

    <button :class="{active: buttons['button3']}">Button 3</button>