Martyn Ball
Martyn Ball

Reputation: 4885

Vue Component, assign computed property to data

i'm trying to set a component's data to a computed property value, as this fetches some localStorage data and manipulates it slightly.

I would then once the component is mounted listen for changes within the localStorage, and if my key is updated then fetch this value again, run it through my computed property and pass it back to the view.

However i'm getting the following error:

ReferenceError: ids is not defined
    at a.render (vue.js:4)
    at a.e._render (vue:6)
    at a.r (vue:6)
    at un.get (vue:6)
    at new un (vue:6)
    at vue:6
    at a.bn.$mount (vue:6)
    at a.bn.$mount (vue:6)
    at init (vue:6)
    at vue:6

This is my component:

Vue.component('favourites-button', {
    render() {
        return this.$scopedSlots.default({
            count: this.ids.length
        });
    },
    data: function() {
        return {
            ids: this.getFavourites()
        }
    },
    mounted() {
        const self = this;
        Event.listen('favourites-updated', function (event) {
            console.log('updated external');
        });
        window.addEventListener('storage', function (e) {
            if (e.key === 'favourites') {
                console.log('updated');
                self.ids = self.getFavourites();
            }
        });
    },
    methods: {
        getFavourites: function() {
            let favourites = localStorage.getItem('favourites');
            return favourites.split(',').filter(id => !!id);
        }
    }
});

Edit:

Updated my code, getting the same error however when the storage change event is fired.

Edit 2:

Turns out my template was expecting toggle within my scope but I removed this from my $scopedSlots.

Upvotes: 4

Views: 10813

Answers (2)

Erik Terwan
Erik Terwan

Reputation: 2780

You can use computed properties for this, but you'd have to define a getter and a setter.

computed: {
  fullName: {
    // getter
    get: function () {
      return localStorage.getItem('favourites')
    },
    // setter
    set: function (newValue) {
      localStorage.setItem('favourites', newValue)
    }
  }
}

Much cleaner imo than using the mounted callback, setting data and then watching for changes.

Upvotes: 3

Martin Bean
Martin Bean

Reputation: 39389

Computed properties work on data/props, so you can’t use them in data itself.

Instead, just set the default value of the data key to what’s in local storage:

data: function () {
    return {
        ids: function() {
            let favourites = localStorage.getItem('favourites');
            return favourites.split(',').filter(id => !!id);
        }
    };
}

Upvotes: 2

Related Questions