Jousi
Jousi

Reputation: 476

Props not being assigned to data() attribute in Vue

I am creating a Vue component, which should refresh restaurants depending on user dynamically selected filters.

Therefor I have to update the filteredRestaurants in the data() function of my Vue component. However, at first, when the Vue component is rendered, it takes the restaurant information from the "restaurants" prop.

I have tried to insert the "restaurants" into the filteredRestaurants data attribute to set it as a default value. Unfortunatelly then the stores wouldnt show at tall, as if the "restaurants" prop is inserted after the filteredRestaurants is assigned its value.

My question is, how can i get the "restaurants" prop into filteredRestaurants so that I can later on, re-render the Vue component when the user changes the filters.

<template lang="html">
  <div class="test">
    <Filters></Filters>
  <div>
    <ul class="o-list c-stores">
      <Result v-bind:total="restaurants.length" v-bind:open="isOpen" v-on:toggle="toggleRestaurantList"></Result>
      <li v-for="(restaurant, index) in restaurants" class="c-stores__location" :class="{'first': isFirst(index), 'last': isLast(index, restaurants)}">
        <Location :index="index" :store="restaurant" :link="() => setCurrentRestaurant(restaurant)"></Location>
      </li>
    </ul>
  </div>
  </div>
</template>

<script>
import eventHub from './../../event-hubs/storefinder'
import Location from './Location'
import Filters from './Filters'
import Result from './Result'

export default {
  props: ["restaurants", "isOpen", "currentSearch"],
  data() {
    return {
      attributes : [],
   // Here I am assigning the prop
      filteredRestaurants : this.restaurants
    }
  },
  head: {
    title: function () {
      return {
        inner: this.$t('storefinder.overview')
      }
    },
    meta: function functionName() {
      return [{
          name: 'og:title',
          content: this.$t('storefinder.overview') + ' - ' + this.$t('storefinder.name'),
          id: "og-title"
        },
        {
          name: 'description',
          content: this.$t('storefinder.description'),
          id: "meta-description"
        },
        {
          name: 'og:description',
          content: this.$t('storefinder.description'),
          id: "og-description"
        },
      ]
    }
  },
  components: {
    Location,
    Filters,
    Result
  },
  methods: {
    toggleRestaurantList() {
      eventHub.$emit('showRestaurantList');
    },
    setCurrentRestaurant(restaurant) {
      this.trackRestaurantSelect(restaurant.publicNameSlug);
      this.$router.push({
        name: "store",
        params: {
          restaurant: restaurant.publicNameSlug
        }
      });
    },
    trackRestaurantSelect(restaurantName) {
      dataLayer.push({
        'event': 'GAEvent',
        'eventCategory': 'restaurants',
        'eventAction': 'clickResult',
        'eventLabel': restaurantName,
        'eventValue': undefined,
        'searchTerm': this.currentSearch && this.currentSearch.toLowerCase(),
        'amountSearchResults': 1
      });
    },
    created() {
      eventHub.$on('addFilterTheRestaurants', (attribute) => this.attributes.push(attribute));
      eventHub.$on('removeFilterTheRestaurants', (attribute) => this.attributes = this.attributes.filter(item => item !== attribute));
    },
    isLast: function (idx, list) {
      return idx === list.length - 1;
    },
    isFirst: function (idx) {
      return idx === 0;
    },
  }
}
</script>

The only way this worked, was when I had the filteredRestaurants as a function which returned "restaurants", and I called it inside the Vue template:

filteredRestaurants(){
  return this.restaurants
}

Any help appreciated.

Upvotes: 2

Views: 1545

Answers (1)

thanksd
thanksd

Reputation: 55634

If I understand your question correctly, you are looking for a computed property:

computed: {
  filteredRestaurants() {
    return this.restaurants;
  }
}

This will update whenever the value of this.restaurants changes.

Upvotes: 2

Related Questions