Robert
Robert

Reputation: 493

Updating property when promise is resolved

Expected result: data from response is displayed on modal

Actual result: data from response is not displayed on modal

Context: I'm using a form to submit data to a search function with a promise to get results from a db. When I submit, I also open a modal to display the results. The modal already opens with a property called allResults that is empty. I'm trying to understand how to bind the data that I get from the resolved promise to the allResults property connected to the modal. Or in other words, how to trigger a property "refresh" when promise gets resolved. When I implement either a watch or computed property they get called before the data is returned.

Properties:

data () {
  return {
    allResults: [],
    query: ''
}} 

The search function uses graphql apollo:

onSubmit () {
  this.$apollo.query({
    query: FIND_PEOPLE,
    variables: {
      name: this.query
    }
  }).then((response) => {
        let a = response.data.given_names  # array
        let b = response.data.family_names # array
        let c = []

        a.forEach(function(el) {
          if (!c.includes(el)) {
            c.push(el)
          }
        })
        var result = c.map(a => a.id);
        b.forEach(function(el) {
          if (!result.includes(el.id)) {
            c.push(el)
          }
        })

        this.allResults.people = []
        this.allResults.people = c
        this.allResults.clubs = response.data.clubs
  });
}

The form:

<b-nav-form @submit="onSubmit">
  <b-form-input size="sm" class="mr-sm-2" type="text" v-model="query" id="navbar-search-input" />
  <b-button size="sm" class="my-2 my-sm-0" v-b-modal="'search-results-modal'" type="submit">Zoek</b-button>
</b-nav-form>

The modal:

  <SearchResultsModal :all-results="allResults" :query="query"/>

The modal component:

<b-modal hide-footer ref="searchResultsModal" id="search-results-modal">
<p>{{"Searchterm: " + this.query}}</p>

<ul v-for="result of this.allResults.people" :key="result.id">
  <li><b-link @click="selectResult('person', result.id)">{{result|personFullName}}</b-link></li>
</ul>
</b-modal>

Props:

props: ['allResults', 'query'],

Additional context:

Please advise

Upvotes: 2

Views: 764

Answers (1)

Phil
Phil

Reputation: 164871

This is a data initialisation and reactivity issue.

You initially set allResults to an empty array, cool. But then you appear to be assigning it an object, indicated by your use of this.allResults.people.

Vue wasn't aware of the people property on allResults so it cannot react to it.

Initialise your data so Vue knows about its properties

data () {
  return {
    query: '',
    allResults: { // an object, not an array
      people: [],
      clubs: [] // assuming this is also an array
    }
  }
}

See https://v2.vuejs.org/v2/guide/reactivity.html

Upvotes: 1

Related Questions