Search code examples
javascriptvuejs2axiosdropdown

Vue.js how to launch axios.get in component after click on parent dropdown button?


I select the currency in the parent component of Vue using bootstrap select:

<template>
...
<div class = "dropdown">
    <button class="btn btn-secondary dropdown-toggle" type="button"> {{currency}} </ button>
    <div class = "dropdown-menu">
        <button class = "dropdown-item" @ click = "currencyChange ('USD')"> USD </ button>
        <button class = "dropdown-item" @ click = "currencyChange ('EUR')"> EUR </ button>
    </div>
</div>
...
<div class = "box">
    <box v-bind: currency-name = 'currency' />
</div>
<template>

<script>
...
data () {
    return {
        currency: 'USD'
    }
},
components: {
    box: component
},
methods: {
    currencyChange (currency) {
        this.currency = currency;
    }
}
...
</script>

In the child component "box" I get data from server via the axios.get call and render it:

<script>
...
props: ['currencyName'],
data () {
  return {
    boxData: {},
  }
},
created () {
  axios.get (URL + this.currencyName)
    .then (response => {
      this.Data = response.data;
    })
    .catch (e => {
      this.errors.push (e)
    })
},
...
</script>

The problem is that if the EUR currency is selected, I never send new query to the server and data in the box component remains the same, for the 'USD' currency except currencyChange variable. If rename "created" hook to "updated" in component, everything starts to work as it should, with one exception - there are constant calls to the server.

How can I fix this wrong behaviour into a single call to the server only after dropdown click?


Solution

  • You can use the watch property to achieve this.

    <script>
      ...
      props: ['currencyName'],
      data () {
        return {
          currentCurrency: this.currencyName,
          boxData: {},
        }
      },
      watch: {
        currentCurrency() {
          this.getData();
        }
      },
      methods: {
        getData() {
          axios.get (URL + this.currentCurrency)
          .then (response => {
            this.Data = response.data;
          })
          .catch (e => {
            this.errors.push (e)
          })
        },
      }
      ...
    </script>
    

    Take a look at https://v2.vuejs.org/v2/guide/computed.html#Watchers

    EDIT

    As D F suggest you can add immediate: true, to your watcher to trigger it at the component initialization