11

I am trying to have a modal pop up with details of a credit card. The details come from an AJAX request. For some reason the root Vue instance is updating but the component instance is not. This is what I currently have -

HTML:

<!-- View Card Details Modal -->
<!-- Modal -->
<div class="modal fade" id="ccdetails" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">View Card Details</h4>
      </div>
      <card-details cardid="{{$cc->card_id}}" :message="getCCDetails('{{$cc->card_id}}')"></card-details>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <!-- <button type="button" class="btn btn-primary">Save changes</button> -->
      </div>
    </div>
  </div>
</div>

Vue JS:

<script type="text/javascript">
Vue.component('card-details', {
  template: '<div class="modal-body">@{{message}}</div>',
  // data is technically a function, so Vue won't
  // complain, but we return the same object
  // reference for each component instance
 props: ['message', 'cardid']
}),
new Vue({
  el: '#ccdetails',
  data: {
    cardid: '',
    message: ''
  },
  methods: {
        getCCDetails: function (id) {
            console.log(id)
            console.log('calling function')
             axios.get('/card/'.concat(id))
                  .then(function (response) {
                    this.message = JSON.stringify(response.data)
                  }.bind(this))
                  .catch(function (error) {
                    return this.message = 'Sorry there was an error'
                  }.bind(this));
        }
  }
})
</script>

For the output, Root instance has cardid = undefined and message = the output I want. My cardDetails instance has the cardid value correct but message = undefined.

Pierce O'Neill
  • 385
  • 9
  • 22
rbur0425
  • 479
  • 8
  • 26
  • Which version of Vue is it? And, what exactly is $cc variable? – Staszek May 07 '17 at 22:55
  • It is a little confusing. You'll need to add an example for your $cc. in a comment below you claimed there can be multiple $cc - therefore I'd say you are not looping anywhere. Did you ensure that $cc->card_id is not null? – Frnak May 09 '17 at 07:17

3 Answers3

3

You can try events

Add event listener in component:

Vue.component('card-details', {
        template: '<div class="modal-body">@{{message}}</div>',
        // data is technically a function, so Vue won't
        // complain, but we return the same object
        // reference for each component instance
        props: ['cardid'],

        data: {
            message: ''
        },

        mounted() {
            this.$parent.$on("card-details:message", message => {
                this.message = message;
            });
        },
    }),

add emit line in function:

    getCCDetails: function (id) {
        console.log(id)
        console.log('calling function')
        axios.get('/card/'.concat(id))
            .then(function (response) {
                this.message = JSON.stringify(response.data)
                this.$emit('card-details:message', this.message) // <--
            }.bind(this))
            .catch(function (error) {
                return this.message = 'Sorry there was an error'
            }.bind(this));

    }

And make getCCDetails function call only on View Details button click.

sebbz
  • 554
  • 3
  • 11
0

I'm on phone sorry, try this:

  • Set :message="message" in your card-details

  • then in the root Vue element, add a :cardid="{{$cc->card_id}}", and don't forget cardid prop

  • then implement mounted method in the root instance and call getCCDetails(this.cardid) from there.

  • inside getCCDetails set message property

I hope this helps

yazfield
  • 1,233
  • 11
  • 18
  • I didn't want to run in mounted method because there can be anywhere from 1-10 credit cards on a customer's account and I don't want to make 10 requests before the page loads. I want the request to be made when they click the View Details button and the modal pops up. Also, for root Vue element are you saying to add a data array and return cardid="{{$cc->card_id}}" ? – rbur0425 May 05 '17 at 16:17
0

Modal is not for Ajax calls. You must have Ajax calls from controllers.