anu start
anu start

Reputation: 395

Vue UI not updating using axios after closing semantic modal

I have a vue that displays an html table based on an axios call to get a list of points from a db table during mounted. I also have a semantic modal that I use in the same vue to add records to the points db table. During the modal's onHidden, I make the same axios call to update the html table in order to display the new record. However, the html table isn't updating.

<template>
  <div>
    <h1 class="ui header">Points</h1>
    <button class="ui icon button" v-on:click="showModal()">
      <i class="add icon"></i>
    </button>
    <div class="ui modal">
      <div class="header">
        Header Text
      </div>
      <div class="content">
        <div class="ui form">
          <div class="field">
            <label>Date</label>
            <datepicker v-model="newPoint.earnedDate" id="earned_date"></datepicker>
          </div>
          <div class="ui grid">
            <div class="four wide column">
              <div class="ui dropdown" id="name_dd">
                <div class="text">Name</div>
                <i class="dropdown icon"></i>
              </div>
            </div>
            <div class="eight wide column">
              <div class="ui dropdown" id="rule_dd">
                <div class="text">Rule</div>
                <i class="dropdown icon"></i>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="actions">
        <div class="ui black deny button">
          Cancel
        </div>
        <div class="ui positive right labeled icon button">
          Save
          <i class="checkmark icon"></i>
        </div>
      </div>
    </div>
    <table class="ui celled table">
      <thead>
        <tr>
          <th>Date</th>
          <th>Name</th>
          <th>Points</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="point in points">
          <td>{{point.earnedDate}}</td>
          <td>{{point.name}}</td>
          <td>{{point.points}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
  import axios from "axios";
  import Datepicker from 'vuejs-datepicker';

  export default {
    name: 'earnings',
    components: {
      Datepicker,
    },
    data() {
      return {
        points: [],
        newPoint: {
          earnedDate: "1/1/1970",
          name: "",
          points: ""
        },
        earners: [],
        errors: [],
      }
    },
    methods: {
      showModal: function() {
        $('.ui.modal')
          .modal('show');
      },
    },
    mounted () {
    //THIS CALL UPDATES THE HTML TABLE
      axios
        .get('api/earnings')
        .then(response => (this.points = response.data));

      //Set the modal approve and deny callbacks
      $('.ui.modal')
        .modal({
          closable: true,
          onDeny: function () {
            return;
          },
          onApprove: function () {
            /*****************************************
             * Add the new points using web API
             *****************************************/

            //Get the modal values
            var earned_date = $('#earned_date').val();
            var earner_id = $('#name_dd').dropdown('get value');
            var rule_id = $('#rule_dd').dropdown('get value');

            //Call the post route
            axios
              .post('api/earnings', { earnedDate: earned_date, earnerId: earner_id, ruleId: rule_id})
              .then(response => {})
              .catch(e => {
                console.log(e)
              })

            return;
          },
          onHidden: function () {
          //THIS CALL DOES NOT UPDATE THE HTML TABLE
            axios
              .get('api/earnings')
              .then(response => (this.points = response.data));
          }
        });

      //Load the name dropdown on the add new points modal
      $('.four.wide.column .ui.dropdown')
        .dropdown({
          apiSettings: {
            // this url just returns a list of tags (with API response expected above)
            url: 'api/earners/semantic_dd',
            cache: false
          },
        });

      //Load the rule dropdown on the add new points modal
      $('.eight.wide.column .ui.dropdown')
        .dropdown({
          apiSettings: {
            // this url just returns a list of tags (with API response expected above)
            url: 'api/rules/semantic_dd',
            cache: false
          },
        });
    },
    created: function () {
      // Remove the modal so it doesn't duplicate when the user navigates away from the component
      // and then returns to it
      $('.ui.modal').remove();
    }
  }
</script>

Upvotes: 0

Views: 840

Answers (1)

anu start
anu start

Reputation: 395

It looks like the this is not available during the axios call using =>. At the start of mounted I set var self = this and used self.points instead of this.points during onHidden. The binding to the template is working now.

Edit after-the-fact

In Vue.js, use this.$data.property-name which points to the component's properties. See documentation at https://v2.vuejs.org/v2/api/#data

Upvotes: 1

Related Questions