Dustin
Dustin

Reputation: 1

Updating ng-repeat with $http without refreshing browser

I'm going to try to make this short and sweet I will preface this with the typical "I'm new to AngularJS"

I'm loading data into my AngularJS application through the $http service. I have an update button for each row that I need to reach out to my server side method (I already have the api returning the data) and run a sync to this third party application and pull out a Percent Complete number of the running status of the sync (the % complete is being stored in the database) and the new Status

How can I run this update sync and refresh my displayed data with a % complete of the sync?

index.html

<tbody ng-controller="synchronizationController">

        <tr ng-repeat="synchronization in synchronizations">               

            <td><a href ng-href="#/synchronizations/{{synchronization.syncID}}">{{ synchronization.syncName }}</a></td>

            <td>{{synchronization.syncType}}</td>
            <td> 
            <ng-switch on="synchronization.status">
                <div ng-switch-when="0">Idle</div>
                <div ng-switch-when="1">Running</div>
                <div ng-switch-when="2">In Queue</div>
                <div ng-switch-when="3">Failed</div>
                <div ng-switch-when="4">Complete</div>
                </ng-switch>

            <div ng-show="synchronization.status == 1" class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar"
                     aria-valuenow={{synchronization.percentComplete}} aria-valuemin="0" aria-valuemax="100" style="width:auto">{{synchronization.percentComplete}}

                </div>

            <td>{{ synchronization.startTime | date:'medium' }}</td>
            <td>{{ synchronization.endTime | date:'medium'}}</td>


            <td ng-controller="synchronizationUpdate"><button class="btn btn-default" ng-click="updateData(synchronization.syncID, $index)">Update</button></td>
            <td ng-controller="synchronizationUpdate"><button class="btn btn-default" ng-really-click="fullSync(synchronization.syncID)" ng-confirm-click="Full Sync will erase all data. Are you sure?">Full</button></td>

        </tr>
    </tbody>

controller

angular.module('SynchronizationsApp').controller("synchronizationUpdate", function (
$scope, synchronizationFactory) {

     $scope.updateData = function (syncId,index) {

            synchronizationFactory.initiateUpdateSynchronization(syncId, 'Update').success(function (response) {
                console.log("Running Update Sync");
                console.log(response);
                $scope.synchronizations[index] = response.data;

            }).error(function (error) {
                console.log("Failed to run Update!" + error);
            });     
};

factory

angular.module('SynchronizationsApp').factory('synchronizationFactory', function($http, $q, $timeout){

        var exposedAPI = {
            getSynchronization: getSynchronization,
            getSynchronizations: getSynchronizations,
            initiateUpdateSynchronization: initiateUpdateSynchronization
        };

        return exposedAPI;

        function get(url) {

            return $http.get(url).success(function (data) {

                    }).error(function (msg, code) {

                        console.log(msg, code);

                    });
        }

            function getSynchronizations(){
                return get('/api/synchronizations');
            }

            function getSynchronization(syncId){
                return get('/api/synchronizations' + '/' + syncId);
            }

            function initiateUpdateSynchronization(syncId, syncType) {

                return get('dosync' + '/' + syncId + '/' + syncType);
            }

    });

Upvotes: 0

Views: 162

Answers (2)

georgeawg
georgeawg

Reputation: 48968

To have the update button update only an item on its row and not the whole table, pass the $index to the update function:

   <tr ng-repeat="table in tables">
      <td>{{ table.name }}</td>
      <td>{{ table.id }}</td>
      <td>{{ table.sync_status}}</td>
      <td ng-show="table.status == In Progress">{{table.percentComplete}}
      </td>
      <td>
        <!--
        <button class="btn btn-default" ng-click="updateData(table.id)">
          Update</button>
        -->
        <!-- ADD $index -->
        <button class="btn btn-default" ng-click="updateData(table.id,$index)">
          Update</button>
      </td>
    </tr>

Then use that index:

  $scope.updateData = updateData;

  function updateData(tableId, index) {
    $http.get("/sync/" + tableId).success(function(response) {
      $scope.tables[index].percentComplete = response.percentComplete;
    });
  }

The above example updates only the percentComplete column on the row of the individual Update button.

Upvotes: 0

Vladimir M
Vladimir M

Reputation: 4489

You are overriding your tables in the handler (and wiping all the angular magic with it). But you need to update them.

   $scope.tables = response;

change to something like:

$scope.tables.length = 0;
response.forEach(function(a){ $scope.tables.push(a); });

Here is a complete sample for your code:

var app = angular.module("myApp", []);
app.controller('tableController', function($scope, $http) {
  $scope.tables=[];
  tableController();

  function tableController() {
    $http.get("tables.json").success(function(response) {
      $scope.tables.length = 0;
      response.forEach(function(a){ $scope.tables.push(a); });
    });
  }

  function updateData(tableId){
    $http.get("/sync/" + tableId ).success(function(response){
      $scope.tables.length = 0;
      response.forEach(function(a){ $scope.tables.push(a); });
    });

  }
});

https://plnkr.co/edit/pVDOQgoOeiL7lKxsGHhv?p=preview

Upvotes: 1

Related Questions