2

I have a table that holds information from multiple sources (websites). Each row is a different source. The user can refresh the data for each individual row/source/website by clicking a refresh icon, or, the user can update ALL rows by clicking the refresh icon in the header row.

When refreshing, the script actually logs into each website and gets the live data vs getting stale data from the DB.

I would like to have each row update as the data comes when the user clicks on the refresh ALL icon in the header row.

Here's how I structured things currently. It does update the table but only when every single row is complete.

  • Vuejs
  • Laravel Spark (which uses $http.get)
  • Laravel 5.3.31

...

Vue.component('websites', {
// props: [''],
    /**
     * The components data
     */
     data() {
      return {
       userLbProfiles: [],
       spin_icon_many: false,
       showRefreshButton: '',
       refreshTime: '',
       busy: '',
       changeStatus: '',
      };
     },


    /**
     * Bootstrap the component
     .    */
     mounted() {
      var self = this;
      this.fetchLastRefreshTime();
      this.getData();
      this.busy = false;
      this.showRefreshButton = true;
     },



    /**
     * Component's methods
     */
     methods: {

        /**
       * get current stored data from the DB 
       *
       * @return response
       */
       getData() {
        this.changeStatus = true;
        this.$http.get('/get/all/userLbProfiles')
        .then(function (response) {
         console.log(response);
         this.userLbProfiles = response.data;
         this.busy = false;
         this.spin_icon_many = false;
         this.changeStatus = false;
        })
       },

        /**
       * get only ONE row from the DB
       *
       * @return response
       */
       getDataForOne(userLbProfileId, i) {
        this.changeStatus = true;
        this.$http.get('/get/one/userLbProfile/'+userLbProfileId)
        .then(function (response) {
         console.log(response);
         this.userLbProfiles[i] = response.data;
            console.log(this.userLbProfiles[i]+'number: '+i);
         this.busy = false;
         this.userLbProfiles[i].spin_icon = false;
         this.changeStatus = false;
        })
       },




       /**
       * Call the api to log into one website and fetch the live data
       *
       */
       refreshOne(userLbProfileId,i) {
        this.userLbProfiles[i].spin_icon= true;
        this.busy = true;
        this.$http.get('/get/refresh/one'+userLbProfileId)
        .then(function (response) {
         console.log(response);
         this.getDataForOne(userLbProfileId,i);
         // this.getData();
        })
       },


       /**
       * Call the api to log into and update the specified # of websites
       *  next in the list
       *
       */
       refreshMany() {
        this.spin_icon_many = true;        
        this.busy = true;        
        for(i=0; i <= this.userLbProfiles.length-83; i++) {         
         this.userLbProfiles[i].spin_icon= true;         
         this.$http.get('/get/refresh/many'+this.userLbProfiles[i].id)
         .then(function (response) {
          console.log('got response after fetching refresh data for: '+this.userLbProfiles[i].id);
          console.log(response);                   
         });
        }
       },
<get-website-data inline-template>
 <div class="panel panel-default">
  <div class="panel-body">
         <div class="row">
          <div class="col-md-12">
           <form class="form-horizontal" role="form">
            <table class="table table-hover">
             <tr>
              <th>Data Item 1</th>
              <th>Data Item 2</th>
              <th>
              <form>
          <a href=""
           @click.prevent="refreshMany()">
           
           <i v-if="spin_icon_many"
            class="fa fa-fw fa-refresh fa-spin fa-2x">
           </i>
           <i v-else
            class="fa fa-fw fa-refresh fa-2x">
           </i>
          </a>
         </form> -->
       <i class="fa fa-fw fa-refresh fa-2x">         
              </th>
              <th>Last Update</th>
             </tr>


         <tr v-for="(userLbProfile, index) in userLbProfiles">
          <td>
           @{{ dataItem1 }}
          </td>
          <td>
           @{{ dataItem2 }}
          </td>

                  
                                          etc..

What happens with this code is that (obviously) the for loop runs out before I get any response. Each request ranges from 3-15 seconds.

If there's 10 websites, let's say, 10 AJAX calls go out but the first .then block (which calls getData from db) doesn't process until ALL 10 other async calls complete, even if I can see the response it prints in the console.

I would think .then would process individually for that response, but somehow they all know about each other? Probably the for loop?

I also tried calling getDataForOne thinking it might update the row and trick it into updating right away, but I didn't get Vue to recognize the data changed (maybe this is the right route to take?)

Any help is greatly appreciated this has been an ongoing issue for weeks now.

garfbradaz
  • 3,424
  • 7
  • 43
  • 70
  • Replace the content of your loop with a call to `getDataForOne`, this way the logic is not handled in your loop but in the getDataForOne method – Antony Aug 04 '17 at 12:07
  • the problem with that is it takes 3-15 seconds for each request (I updated my post to clarify) so your suggestion would run getData from DB but that data is not updated yet and won't be until the async call is done. – Jonah Klimack Aug 04 '17 at 12:17

1 Answers1

0

Can you show your other part of table content ?

You mean that single table row dosen't update when server response datas ?

possibly it can shot your issue https://v2.vuejs.org/v2/guide/list.html#Caveats ?

tony19
  • 125,647
  • 18
  • 229
  • 307
Simon.Lay
  • 263
  • 2
  • 9