Using a vue-apollo component with different queries on the same page

Viewed 871

I would like to make a wrapper component using Apollo, which receives different GraphQL queries and variables within props, queries GraphQL source and and passes response to its child component. I would like to use this component twice on a page with different queries.

But I think I'm stuck at some point. I end up having both instances of the component working with same inputs: query prop of the first dropdown component is being used in all dropdowns on the page. Although they have a different scope, different keywords and items, all dropdowns on the page are using the query of first dropdown.

Here is my DropdownSearch component. It passes keyword from searchbar component to query-list component:

<template>
  <div class="dropdown-search">
    <div class="dropdown-search-display" @click="toggleDropdown"> 
      <span>{{value[nameProp]}}</span>
      <span class="dropdown-search-dropdown-toggle">
        <i v-if="!isOpen" class="fa fa-caret-down" aria-hidden="true"></i>
        <i v-if="isOpen" class="fa fa-caret-up" aria-hidden="true"></i>
      </span>
    </div>
    <div :class="{ 'dropdown-search-dropdown': true, 'dropdown-search-dropdown--open': isOpen}" >
      <search-bar v-model="searchKeyword" class="dropdown-search-searchbar"></search-bar>
      <div class="dropdown-search-list">
        <query-list
          :query="query"
          :keyword="searchKeyword"
          :listItemComponent="ListItem"
        ></query-list>
      </div>
    </div>
  </div>
</template>

<script>
const ListItem = {
  template: '<div class="dropdown-search-list-item">{{record.name}}</div>',
  props: {
    record: { required: true },
  },
};

export default {
  name: 'dropdownSearch',
  props: {
    name: String,
    nameProp: String,
    value: Object,
    query: Object,
  },
  components: {
    'dropdown-list-item': ListItem,
  },
  data() {
    return {
      isOpen: false,
      searchKeyword: '',
      ListItem,
    };
  },
  methods: {
    toggleDropdown() {
      this.isOpen = !this.isOpen;
    },
  },
};
</script>

QueryList component, which is using Apollo to make queries and displays a list of results:

<template>
  <div class="">
    <loading-indicator :isLoading="loading > 0"></loading-indicator>
    <ul class="app__list">
      <li class="app__list-item" v-for="item in items" :key="item.id">
        <component
          :is="listItemComponent"
          :record="item"
        ></component>
      </li>
    </ul> 
  </div>
</template>

<script>
export default {
  name: 'queryList',
  props: {
    query: Object,
    keyword: String,
    listItemComponent: { required: true },
  },
  data() {
    return {
      items: [],
      loading: 0,
    };
  },
  apollo: {
    items: {
      query() {
        return this.query;
      },
      variables() {
        return {
          keyword: this.keyword || '',
        };
      },
      loadingKey: 'loading',
    },
  },
};
</script>

This is how I use Dropdown Search components on a page:

   <label class="edit-record-field">
        <span class="edit-record-field-label">Category</span>
        <dropdown-search 
          class="edit-record-field-input"
          v-model="record.category"
          :nameProp="'name'"
          :query="getCategories"
        ></dropdown-search>  
   </label>
      <label class="edit-record-field">
        <span class="edit-record-field-label">Location</span>
        <dropdown-search 
          class="edit-record-field-input"
          v-model="record.location"
          :nameProp="'name'"
          :query="getLocation"
        ></dropdown-search>  
   </label> 

I'm looking for a solution. I would be grateful if you could help me to make my components working.

0 Answers
Related