[SalesForce] Displaying Account Details in Table form using AngularJs

Can anyone tell me how to display Table form for the account name and account id in visualforce page using AngularJs?
I have created the Visualforce for this use case.
But I didnt get Account details in table form.
My VFP code as follows

<apex:page standardStylesheets="false" showHeader="false" sidebar="false" controller="TableFormatContr">   
<html>  

  <head>   

    <script type="text/javascript" src="{!URLFOR($Resource.newformvalidation,'/newformvalidation/angular.js')}"></script>
    <script src="https://cdn.jsdelivr.net/angular.ngtable/0.3.3/ng-table.js"></script>

    <link href="{!URLFOR($Resource.newformvalidation,'/newformvalidation/bootstrap.css')}" rel="stylesheet"/>

    <script src="https://cdn.jsdelivr.net/angular.ngtable/0.3.3/ng-table.css"></script>


    <script >
        var app = angular.module('main', ['ngTable']).
            controller('DemoCtrl', function($scope, ngTableParams) {

           var data=[];

                Visualforce.remoting.Manager.invokeAction(
                            '{!$RemoteAction.TableFormatContr.getAccount}',

                            function(result, event){
                                if (event.status) {
                                //Result contains list of account names and account id
                                   data=result;
                                   alert(data.length);
                                   alert("First Account Name:"+data[0].Name);//It display the first account name
                                } else if (event.type === 'exception') 
                                    alert(event.message);

                            }, 
                            {escape: true}
                        );



       $scope.tableParams = new ngTableParams({
            page: 1,            // show first page
            count: 10           // count per page
            }, {
                  total: data.length, // length of data
                  getData: function($defer, params) {
                      $defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
                  }
               }
       );



});

    </script>
</head>

<body id="body1" ng-app="main" ng-controller="DemoCtrl" onload="getContact()">


    <table ng-table="tableParams" template-pagination="custom/pager" class="table">
        <tr ng-repeat="user in $data">
            <td data-title="'Id'">
                {{user.Id}}
            </td>
            <td data-title="'Name'">
                {{user.Name}}
            </td>
        </tr>
    </table>
    <script type="text/ng-template" id="custom/pager">
        <ul class="pager ng-cloak">
          <li ng-repeat="page in pages"
                ng-class="{'disabled': !page.active, 'previous': page.type == 'prev', 'next': page.type == 'next'}"
                ng-show="page.type == 'prev' || page.type == 'next'" ng-switch="page.type">
            <a ng-switch-when="prev" ng-click="params.page(page.number)" href="">&laquo; Previous</a>
            <a ng-switch-when="next" ng-click="params.page(page.number)" href="">Next &raquo;</a>
          </li>
            <li> 

            </li>
        </ul>
    </script>

</body>
</html>
</apex:page>

Controller:

global with sharing class TableFormatContr {

    public TableFormatContr(){}

    @RemoteAction
    global static List<Account> getAccount () {

        List<Account> accList=[select Id,Name from Account];
        return accList;

    }
}     

The Above Code Doesn't provide the Account Details in Table form?
I dono whats wrong my code?
Please someone help on this.

Thanks in advance
​Karthick

Best Answer

This will produce the table:

<script>
var app = angular.module('main', ['ngTable'])
app.controller('DemoCtrl', function($scope, ngTableParams) {
    var data = [];
    Visualforce.remoting.Manager.invokeAction(
       '{!$RemoteAction. TableFormatContr.getAccount}',
       function(result, event) {
            if (event.status) {
                data = result;
                $scope.tableParams = new ngTableParams({
                    page: 1,            // show first page
                    count: 10           // count per page
                }, {
                    total: data.length, // length of data
                    getData: function($defer, params) {
                        $defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
                    }
                });
                $scope.$apply();
            } else if (event.type === 'exception') {
                alert(event.message);
            }
        }, 
        {escape: true}
    );
});
</script>

A key point about this sort of JavaScript is that data is returned to the browser asynchronously by code such as Visualforce.remoting.Manager.invokeAction. That means that you cannot rely on any values until its callback function - the second argument - has executed. The easiest way to ensure that the values you need are available is to put the logic that needs the data in the callback function. (There are probably more elegant patterns but this is a pragmatic fix for your code.)

In many cases Angular can automatically notice changes to values in the scope and render the view accordingly. For cases where it can't, there is $scope.$apply() to tell Angular to do the render and that appears necessary in this case.

I strongly recommend that if you are going to use Angular that you invest time in learning more about it. I found the https://egghead.io/ videos very helpful for that - they cover key topics in 5 minutes or less.