Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular JS : updating object values in scope after the backend call

I have an angular js html page having a HTML table. This has some 100 rows. The user selects 10 or 15 rows and makes a backend call. The backend call is made using $.ajax({...}) to do the processing and update the database. After processing, the backend returns 2 or 3 records back to the screen. These returned objects will have new statuses and some new values. So I need to sync these statuses back to the same object in my scope so they get reflected on the screen.

I know we can loop through each object and update the status. But as the size of the data is too high (sometimes even 1000 rows), I want to know if there is any readily available feature in angular to do this job. If no such feature is available in Angular, please suggest any other free open source tools that can come to help for me.

I am attaching the code snippet here. Just because of confidentiality reasons, I converted my problem into customer account scenario

<table >
     <thead >
       <tr>  
     <th >Customer Name</th>
     <th >Account Number</th>
     <th >Status </th>
     <th >Date</th>                 
       </tr>
    </thead>
    <tbody  ng-repeat="customer in customerList">
       <tr  ng-repeat="account in customer.accounts"  >
    <td>{{customer.name}}</td>
    <td>{{account.acctNum}}</td>
    <td>
         <input type="checkbox"  ng-model="account.acctId"  ng-change="selectThisAccount(account)" /> {{account.status}}
    </td>
    <td>{{account.activationTimestamp}}</td>
       </tr>
    </tbody>
</table>
<input  type="button" value="Activate Accounts"   ng-click="activateAccounts()"  />

Controller
===========

$scope.customerList = ....
// I have my customer list retrieved by way of another call and the data is assigned to the scope.customerList variable

$scope.selectedAccounts = [];
$scope.selectThisAccount = function(account) {
      $scope.selectedAccounts.push(account);
};


$scope.activateAccounts = function() {
    $scope.successfullyActivatedAccounts = [];
    $scope.successfullyActivatedAccounts = AccountService.activateAccounts($scope.selectedAccounts);
}

AccountService.js
======================
    this.activateAccounts = function(accounts)
    {

    var accountRequest ={};
    accountRequest.accountList = accounts;

     return $.ajax({
          type : 'POST',
          url: 'activateAccounts',
          data:JSON.stringify(accountRequest),
          dataType: "json",
          contentType: "application/json",
          success: function(accountresponse){
         return accountresponse.accountList;    
          },   
          error : function(xhr, ajaxOptions, thrownError) {
             hideReportMessage();
             alert( "Error: " + xhr.responseText + "\n" + thrownError );
          }
      });  
    },

To explain this, a customer can have multiple accounts and each account can be in different states. The end user will see a list of customer accounts, selects a list of them and tries to activate accounts. Only those account objects that are activated will be returned by the server. I need to update the value of account.status identifying the right object without looping through the entire list.

Please help.

like image 718
user2928913 Avatar asked Oct 20 '22 16:10

user2928913


1 Answers

So Here is a plunker. I've taken your example. And made a few changes. I use $timeout to replicate $http and because of this you can uses angular promises. (the .then) after the code in that is executed a digest cycle is run. And since the references ($scope.selectedAccounts) have changed the ng-repeats refresh those that have changed. Its very easy to use $http with promises to update the view.

In the plunk, You'll notice that only the successfullyActivatedAccounts actually activate because they were the only ones that successfully returned (dummy data). Also the loop in activateAccounts can be optimized if you know a for sure the ordering of the return value. But overall the performance of this should be fine.

I updated the data set to be as large as plunker could handle. Activating performance is still pretty instant.

like image 197
calebboyd Avatar answered Oct 23 '22 14:10

calebboyd