Refresh components without restarting app

ISSUE

I have two component pages in my dashboard, the index.html (tabbed view) the second is add-card.html i want to achieve this when the add card form is added the dashboard index.html (tabs) dom will be refresh/updated to display the new card on the slider.

WHAT I HAVE TRIED

I have tried adding a set interval function to always load the ajax request, but that returns a “to may requests” error

setInterval(function () { 

				window.Framework7.request.get(cardDataURL, cardData, function (data) {

					d_data = JSON.parse(data);

					window.cards = d_data;

					// d_data = 0;

					console.log(window);

					noPaymentCard = '<h4 class="text-size-15 text-center josefin-sans-bold-font grey-text-color">No payment card added </h4>';

					if (d_data.length == 0) {

						$$('.payment-card-slides').html(noPaymentCard);

					} else {

						if (d_data.length >= 1) {

							swiperContainer = '<div class="swiper-container swiper-init demo-swiper">' +
								'<div class="swiper-wrapper">';

							var html = '';

							$.each(d_data, function (key, value) {

								/* 
								  MASKED CARD NUMBER
								  http://jsfiddle.net/QmdZ3/
	
								  ADD SPACE AT EVERY FOURTH CHARACTER
								  https://stackoverflow.com/questions/53427046/how-to-add-space-between-every-4-characters-in-javascript
								*/

								var card_number = value.card_number;
								var remove_white_space = card_number.replace(/ /g, '');
								var masked_card_number = remove_white_space.replace(/.(?=.{4})/g, 'X');

								var masked_card_number = masked_card_number.match(/.{1,4}/g);

								var spaced_masked_card_number = masked_card_number.join(' ');

								var masked_card_number = spaced_masked_card_number;

								html += '<div class="swiper-slide">';
								html += '<div class="payment-card">';
								html += '<div class="row resizable">';
								html += '<div class="col-50">';
								if (value.card_type == "visa") {
									html += '<img class="atm-logo" src="assets/user/visa-logo.png" alt="Visa Logo">';
								}
								if (value.card_type == "mastercard") {
									html += '<img class="atm-logo" src="assets/user/mastercard-logo.png" alt="MasterCard Logo">';
								}

								html += '</div>';
								html += '<div class="col-50">';
								html += '<label class="radio float-right"><input id="card-'+ value.id +'" type="radio"><i class="icon-radio"></i></label>';
								html += '</div>';
								html += '</div>';
								html += '<h2 class="text-size-20 text-center josefin-sans-bold-font gazelle-blue-text">' + masked_card_number + '</h2>';
								html += '<div class="row resizable">';
								html += '<div class="col-50">';
								html += '<h6 class="text-size-10 text-center josefin-sans-light-font grey-text-color">Name</h6>';
								html += '<h4 class="text-size-15 text-center josefin-sans-bold-font grey-text-color uppercase">' + value.card_holder_name + '</h4>';
								html += '</div>';
								html += '<div class="col-50">';
								html += '<h6 class="text-size-10 text-center josefin-sans-light-font grey-text-color">Valid Thru</h6>';
								html += '<h4 class="text-size-15 text-center josefin-sans-bold-font grey-text-color">' + value.card_expiration + '</h4>';
								html += '</div>';
								html += '</div>';
								html += '</div>';
								html += '</div>';

							});

							$('.swiper-wrapper').html(html);



							var endSwiperContainer = '</div >' +
								'</div >';

						}
					}
				});
				
			 }, 10000); 

WHAT I HAVE RESEARCHED
I saw some links that templates can be refreshed with

self.$setState();

How can i achieve this inside a jquery event handler?

SCREENSHOT

CODE

 $("#add-card").click(function () {

        var cardNumber = $("#card-number");
        var cardHolderName = $("#card-holder-name");
        var valdTru = $("#expiration");
        var cvc = $("#cvc");

        console.log(window);

        /* SPLIT VALID TRU INPUT */

        var date = valdTru.val();
        var parts = date.split('/');
        var month = parts[0];
        var year = parts[1];

        // validate the card number

        validateCard = $.payform.validateCardNumber(cardNumber.val());

        if (validateCard == false) {

          toastCenter = window.app.toast.create({
            text: 'Invalid Card Number',
            position: 'center',
            closeTimeout: 2000,
          });

          toastCenter.open();

          return false;

        }

        // validate the expiration

        validateExpiration = $.payform.validateCardExpiry(month, year);

        if (validateExpiration == false) {
          
          toastCenter = window.app.toast.create({
            text: 'Invalid Valid Thru',
            position: 'center',
            closeTimeout: 2000,
          });

          toastCenter.open();

          return false;
        }

        // validate the cvc

        validateCvc = $.payform.validateCardCVC(cvc.val());

        if (validateCvc == false) {

          toastCenter = window.app.toast.create({
            text: 'Invalid CVC Number',
            position: 'center',
            closeTimeout: 2000,
          });

          toastCenter.open();

          return false;

        }


        // send the card detils to the server.

        cardType = $.payform.parseCardType( cardNumber.val() );
        token = window.localStorage.getItem("login-token");
        userId = window.localStorage.getItem("user-id");

        

        window.app.request.post(window.app.data.settings.apiUrl + "/api/v1/paymentcards", {
          card_type: cardType,
          card_number: cardNumber.val(),
          card_holder_name: cardHolderName.val(),
          card_expiration: valdTru.val(),
          card_cvc: cvc.val(),
          token: token,
          user_id: userId,
        }, function (data) {

          var self = this;

          d_data = JSON.parse(data); // decoded json data

          if (d_data.error_msg) {

            data = d_data;

            // create toast
            toastCenter = window.app.toast.create({
              text: 'Oops! ' + data.error_msg,
                position: 'center',
              closeTimeout: 2000,
            });

            toastCenter.open();

          }


          if (d_data.success_msg) {

            data = d_data;

            // create sweet alert
            // swal("Great!", data.success_msg, "success");

            imageURL = "assets/user/card-added.png";

            swal({
              title: "Great!",
              text: data.success_msg,
              icon: imageURL,
            });

            // add the new card to the dom.

            var page = $$('.page[data-name="user-dashboard"]')[0].f7Page;
            var self = page.$el[0].f7Component;
            self.$setState({
              d_data: data,
            });

          }

        });


      });

I definitely would never use a setInterval or setTimeout for background refreshing. You can use custom events, to notify components about something changed, and let components decide itself if they would like to refresh something. This is a observer-like design pattern.

When for example you’ve sent a new item to the server, and would like to refresh a component which contains a list where this new item should show up, you can do something like:

— Component where you send item to the server —

<template>
...
</template>
<script>
return {
  methods: {
    add_item: () => {
      // add this where you save or update your item to the server
     
      this.$app.request.post('https://server/add-item', { new_item: my_new_item }, (response) {
        this.$app.emit('item-added'); // or for example 'items-changed' if items can be deleted as well
      }

    }
  }
</script>

— Component containing list —

<template>
...
  <ul>
    {{#each items}}
      <li id="item-{{id}}">
        {{name}}
      </li>
    {{/each}}
  </ul>
...
</template>
<script>
return {
    on: {
	pageInit: function(e, page) {
	    this.$app.on('item-added', this.do_refresh);
	},
	pageBeforeRemove: function(e, page) {
	    this.$app.off('item-added', this.do_refresh);
	},
    },
    methods: {
      do_refresh: function(e) {

        this.$app.request.post('https://server/items', {}, (data_items) => {

          this.$setState({
            items: data_items.items
          });

        });
      }
    }
}
</script>

Please note that in this case, it is recommended to add a unique id attribute to the list items.