5

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.

5
  • The backend restful service sends JSON objects. Commented Jan 23, 2014 at 3:24
  • I dont have control over changing the service call from $.ajax to $http. It is a reusable service call which is working fine and I just need to make use of it. The backend is spring controller that sends java object list converting into a JSON and each row in the table is an object. Please elaborate if you think I didnot properly get your question "What type of objects are these". Commented Jan 23, 2014 at 3:36
  • Sorry, If you show some controller and markup we might be able to help Commented Jan 23, 2014 at 3:42
  • @calebboyd, I have updated my question with the code snippet explaining the problem more in detail. Please help. Thanks. Commented Jan 23, 2014 at 4:29
  • 1
    Angular does not say anything about size of data . If you use ng-repeat over 1000 rows it could be a performance problem . One more point is that you should replace $.ajax with $http calls and make use of angular promises Commented Jan 23, 2014 at 5:59

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks very much. I am able to solve the problem with your suggestion.
You should consider $resource instead $http to use $promise
0

I suppose using ng-model can solve your problem naturally. TO be more specific, suppose all your data in the 1000-row table are retrieved in your Controller, and you have saved the dataset in your Controller as $scope.dataset. Then when you invoke ajax to update some of the rows, you can simply update the ajax result into your $scope.dataset (the data), then the table (the view) will get updated itself.

To avoid going thru all the 1000 rows in $scope.dataset (when you've got ajax result), in order to match which entry is updated, you can also simply add an index field for each entry (or have all entries sorted), at server side. Then you can access any entry in $scope.dataset using the index.

5 Comments

Are you saying - if I sort all the elements and add an index number for each row in the backend and send them across to the HTML page and load it, it can be used later to locate the object for update? OR is it the $index you are mentioning?
1. Seems Angular $index does not help in your case. 2. If your purpose is to avoid writing the code stuff to find out which entry has been updated, you can use Angular filter (by specifying one or more matching fields to locate an entry in the dataset) or the 3rd party Underscore.js to manipulate your dataset. 3. If what you want is to totally avoid the iteration of the 1000 rows, what I can think of is to convert the dataset from Array to a Map-like structure, indexed by each entry's unique numeric or string Key - but this seems also an iteration operation...
I will try your points mentioned, But I have just updated my question more in detail with code snippet. Can you please have a look and see if you can advice me in specific. Thanks.
Sorry for asking again. Here my data set is a List with in another list. As mentioned above, the required account object is present in the accountList which is present inside customer list.
As long as you use Array, you have to loop thru it to look up one specific entry. So you can either convert it into Map-like structure so that you can directly access it (e.g. customer['google']['Mike']), or you can try to use $filter or underscore.js to locate that entry.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.