locked
Paginating and Sorting a WebApi ResultSet using AngularJs RRS feed

  • Question

  • User1758988721 posted

    Hi, I am pretty new to AngularJs and i have a project that requires that i use angular with my views because am calling a webApi Restful service(Json).

    The problem am having is, when i pass a hard-coded array object into Angular, it works fine and everything looks good. But whenever i pass the result call from Api into the array object, it does not pass any value. i.e. the table becomes empty with no data. I realized the $Items variable is not getting populated with the Json result.

    Below is my working code when i hard-code values into the array:

    var myModule = angular.module('myModule', []);

    myModule.controller('ctrlJobs', function ($scope, $filter, $http) {

    // init
    $scope.sort = {
    sortingOrder: 'id',
    reverse: false
    };

    $scope.gap = 5;

    $scope.filteredItems = [];
    $scope.groupedItems = [];
    $scope.itemsPerPage = 5;
    $scope.pagedItems = [];
    $scope.currentPage = 0;

    $scope.items= [
    { "id": 1, "name": "name 1", "description": "description 1", "field3": "field3 1", "field4": "field4 1", "field5 ": "field5 1" },
    { "id": 2, "name": "name 2", "description": "description 1", "field3": "field3 2", "field4": "field4 2", "field5 ": "field5 2" },
    { "id": 3, "name": "name 3", "description": "description 1", "field3": "field3 3", "field4": "field4 3", "field5 ": "field5 3" },
    { "id": 4, "name": "name 4", "description": "description 1", "field3": "field3 4", "field4": "field4 4", "field5 ": "field5 4" },
    { "id": 5, "name": "name 5", "description": "description 1", "field3": "field3 5", "field4": "field4 5", "field5 ": "field5 5" },
    { "id": 6, "name": "name 6", "description": "description 1", "field3": "field3 6", "field4": "field4 6", "field5 ": "field5 6" },
    { "id": 7, "name": "name 7", "description": "description 1", "field3": "field3 7", "field4": "field4 7", "field5 ": "field5 7" },
    { "id": 8, "name": "name 8", "description": "description 1", "field3": "field3 8", "field4": "field4 8", "field5 ": "field5 8" },
    { "id": 9, "name": "name 9", "description": "description 1", "field3": "field3 9", "field4": "field4 9", "field5 ": "field5 9" },
    { "id": 10, "name": "name 10", "description": "description 1", "field3": "field3 10", "field4": "field4 10", "field5 ": "field5 10" }

    .........

    ]

    var searchMatch = function (haystack, needle) {
    if (!needle) {
    return true;
    }
    return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
    };

    // init the filtered items
    $scope.search = function () {

    $scope.filteredItems = $filter('filter')($scope.items, function (item) {

    for (var attr in item) {
    if (searchMatch(item[attr], $scope.query))
    return true;
    }
    return false;
    });
    // take care of the sorting order
    if ($scope.sort.sortingOrder !== '') {
    $scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sort.sortingOrder, $scope.sort.reverse);
    }
    $scope.currentPage = 0;
    // now group by pages

    $scope.groupToPages();
    };


    // calculate page in place
    $scope.groupToPages = function () {
    $scope.pagedItems = [];

    for (var i = 0; i < $scope.filteredItems.length; i++) {
    if (i % $scope.itemsPerPage === 0) {
    $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [$scope.filteredItems[i]];
    } else {
    $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
    }
    }
    };

    $scope.range = function (size, start, end) {
    var ret = [];
    console.log(size, start, end);

    if (size < end) {
    end = size;
    start = size - $scope.gap;
    }
    for (var i = start; i < end; i++) {
    ret.push(i);
    }
    console.log(ret);
    return ret;
    };

    $scope.prevPage = function () {
    if ($scope.currentPage > 0) {
    $scope.currentPage--;
    }
    };

    $scope.nextPage = function () {
    if ($scope.currentPage < $scope.pagedItems.length - 1) {
    $scope.currentPage++;
    }
    };

    $scope.setPage = function () {
    $scope.currentPage = this.n;
    };

    // functions have been describe process the data for display
    $scope.search();

    ...........

    //This my webApi call

    $scope.items = [];

    function getData() {
     $http.get('http://localhost: XXXXX/api/job/').
     success(function (data) {

    for(var i=0; i<data.Length; i++){

    $scope.items.push(data[i]);

    }

    }).
    error(function () {
    alert("Error occurred");
    });
    };

    var searchMatch = function (haystack, needle) {
    if (!needle) {
    return true;
    }
    return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
    };

    // init the filtered items
    $scope.search = function () {

    $scope.filteredItems = $filter('filter')($scope.items, function (item) {  // filteredItem not getting data $scope.item. I dont really know why

    for (var attr in item) {
    if (searchMatch(item[attr], $scope.query))
    return true;
    }
    return false;
    });
    // take care of the sorting order
    if ($scope.sort.sortingOrder !== '') {
    $scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sort.sortingOrder, $scope.sort.reverse);
    }
    $scope.currentPage = 0;
    // now group by pages

    $scope.groupToPages();
    };


    // calculate page in place
    $scope.groupToPages = function () {
    $scope.pagedItems = [];

    for (var i = 0; i < $scope.filteredItems.length; i++) {
    if (i % $scope.itemsPerPage === 0) {
    $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [$scope.filteredItems[i]];
    } else {
    $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
    }
    }
    };

    $scope.range = function (size, start, end) {
    var ret = [];
    console.log(size, start, end);

    if (size < end) {
    end = size;
    start = size - $scope.gap;
    }
    for (var i = start; i < end; i++) {
    ret.push(i);
    }
    console.log(ret);
    return ret;
    };

    $scope.prevPage = function () {
    if ($scope.currentPage > 0) {
    $scope.currentPage--;
    }
    };

    $scope.nextPage = function () {
    if ($scope.currentPage < $scope.pagedItems.length - 1) {
    $scope.currentPage++;
    }
    };

    $scope.setPage = function () {
    $scope.currentPage = this.n;
    };

    // functions have been describe process the data for display
    $scope.search();

    ...........

    this is my html view:

    <div ng-controller="ctrlJob">


    <table class="table table-striped table-condensed table-hover">
    <thead>

    <tr>
    <th class="id" custom-sort order="'id'" sort="sort">Id&nbsp;</th>
    <th class="name" custom-sort order="'name'" sort="sort">Name&nbsp;</th>
    <th class="description" custom-sort order="'description'" sort="sort">Description&nbsp;</th>
    <th class="field3" custom-sort order="'field3'" sort="sort">Field 3&nbsp;</th>
    <th class="field4" custom-sort order="'field4'" sort="sort">Field 4&nbsp;</th>
    <th class="field5" custom-sort order="'field5'" sort="sort">Field 5&nbsp;</th>
    </tr>
    </thead>
    <tfoot>
    <td colspan="6">
    <div class="pagination pull-right">
    <ul>
    <li ng-class="{disabled: currentPage == 0}">
    <a href ng-click="prevPage()">« Prev</a>
    </li>

    <li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) "
    ng-class="{active: n == currentPage}"
    ng-click="setPage()">
    <a href ng-bind="n + 1">1</a>
    </li>

    <li ng-class="{disabled: (currentPage) == pagedItems.length - 1}">
    <a href ng-click="nextPage()">Next »</a>
    </li>
    </ul>
    </div>
    </td>
    </tfoot>
    <pre>pagedItems.length: {{pagedItems.length|json}}</pre>
    <pre>currentPage: {{currentPage|json}}</pre>
    <pre>currentPage: {{sort|json}}</pre>
    <tbody>
    <tr ng-repeat="item in pagedItems[currentPage] | orderBy:sort.sortingOrder:sort.reverse">
    <td>{{item.id}}</td>
    <td>{{item.companyName}}</td>
    <td>{{item.jobTitle}}</td>
    <td>{{item.postMode}}</td>
    <td>{{item.datePosted}}</td>
    <td>{{item.isApproved}}</td>
    </tr>
    </tbody>
    </table>
    </div>

    Am i getting something wrong. Your assistance will be appreciated

    Friday, July 18, 2014 9:08 AM

Answers

  • User-417640953 posted

    Hi Maduabuchi,

    As other member mentioned, if your local data works fine with the AngularJs but the data returned from web api.

    That means your web api not return the correct data.

    [
    { "id": 1, "name": "name 1", "description": "description 1", "field3": "field3 1", "field4": "field4 1", "field5 ": "field5 1" },

    ........

    ]

    As for above data format, you web api should return json data like below.

    public class TempleModel{
                public int id { get; set; }
                public string name { get; set; }
                public string description { get; set; }
                public string field3 { get; set; }
                public string field4 { get; set; }
                public string field5 { get; set; }
                
            
            }
            public List<TempleModel> GetList()
            {
    
                var model = new List<TempleModel>() 
                { 
                 new TempleModel{ id=1, name="name1", description="description1", field3="field3 1",field4="field4 1",field5="field5 1"},
                 new TempleModel{ id=1, name="name1", description="description1", field3="field3 1",field4="field4 1",field5="field5 1"},
                 new TempleModel{ id=1, name="name1", description="description1", field3="field3 1",field4="field4 1",field5="field5 1"} 
                };
                return model; 
            }

    Then call it from javascript code like below.

    <script> 
        var templeData=[];
            //make sure your ajax call is synchronized
            $.ajax({
                async:false,
                type: "Get", 
                url:"/api/Default/GetList",
                data: "{}",
                dataType: 'Json',
                success: function (result) {
                    alert(result);
                    templeData = result;
                }
            });
    
            var myModule = angular.module('myModule', []);
    
            myModule.co
    
            $scope.gap = 5;
    
            $scope.filteredItems = [];
            $scope.groupedItems = [];
            $scope.itemsPerPage = 5;
            $scope.pagedItems = [];
            $scope.currentPage = 0;
    
            $scope.items=templeData;
            //your other code.............
    
    
    
    </script>

    Hope this helps, thanks.

    Best Regards!

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, July 21, 2014 9:55 PM

All replies

  • User-1423995609 posted

    The problem is that you defined webapi call and further $scope.items population in function getData() that is never being called.

    You need to make a call to getData() function, so that it will actually execute WebApi call and fill out data to your $scope.items array.

    Friday, July 18, 2014 11:17 AM
  • User1758988721 posted

    Thanks for your response Manvel.

    I have done that already, but its not working. Is it possible for me to return an array from the webApi call, i will appreciate if you can still assist

    //This my webApi call

    $scope.items = [];

    getData();

    function getData() {
     $http.get('http://localhost: XXXXX/api/job/').
     success(function (data) {

    for(var i=0; i<data.Length; i++){

    $scope.items.push(data[i]);

    }

    }).
    error(function () {
    alert("Error occurred");
    });
    };

    var searchMatch = function (haystack, needle) {
    if (!needle) {
    return true;
    }
    return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
    };

    // init the filtered items
    $scope.search = function () {

    $scope.filteredItems = $filter('filter')($scope.items, function (item) {  // filteredItem not getting data $scope.item. I dont really know why

    for (var attr in item) {
    if (searchMatch(item[attr], $scope.query))
    return true;
    }
    return false;
    });
    // take care of the sorting order
    if ($scope.sort.sortingOrder !== '') {
    $scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sort.sortingOrder, $scope.sort.reverse);
    }

    ..........

    Friday, July 18, 2014 12:32 PM
  • User-1423995609 posted

    Can you debug your code? Put breakpoint in success method of your web api call, and check whether actually data is being returned. (in other words is data actually has elements in it. From what I understand your problem is whether you have data populated or not. In initial code you've posted, there were no call to getData() method. Now even making a call to a function still doesn't make your application to work, so next thing to check is if WebApi is actually returning something.

    Friday, July 18, 2014 6:26 PM
  • User-417640953 posted

    Hi Maduabuchi,

    As other member mentioned, if your local data works fine with the AngularJs but the data returned from web api.

    That means your web api not return the correct data.

    [
    { "id": 1, "name": "name 1", "description": "description 1", "field3": "field3 1", "field4": "field4 1", "field5 ": "field5 1" },

    ........

    ]

    As for above data format, you web api should return json data like below.

    public class TempleModel{
                public int id { get; set; }
                public string name { get; set; }
                public string description { get; set; }
                public string field3 { get; set; }
                public string field4 { get; set; }
                public string field5 { get; set; }
                
            
            }
            public List<TempleModel> GetList()
            {
    
                var model = new List<TempleModel>() 
                { 
                 new TempleModel{ id=1, name="name1", description="description1", field3="field3 1",field4="field4 1",field5="field5 1"},
                 new TempleModel{ id=1, name="name1", description="description1", field3="field3 1",field4="field4 1",field5="field5 1"},
                 new TempleModel{ id=1, name="name1", description="description1", field3="field3 1",field4="field4 1",field5="field5 1"} 
                };
                return model; 
            }

    Then call it from javascript code like below.

    <script> 
        var templeData=[];
            //make sure your ajax call is synchronized
            $.ajax({
                async:false,
                type: "Get", 
                url:"/api/Default/GetList",
                data: "{}",
                dataType: 'Json',
                success: function (result) {
                    alert(result);
                    templeData = result;
                }
            });
    
            var myModule = angular.module('myModule', []);
    
            myModule.co
    
            $scope.gap = 5;
    
            $scope.filteredItems = [];
            $scope.groupedItems = [];
            $scope.itemsPerPage = 5;
            $scope.pagedItems = [];
            $scope.currentPage = 0;
    
            $scope.items=templeData;
            //your other code.............
    
    
    
    </script>

    Hope this helps, thanks.

    Best Regards!

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, July 21, 2014 9:55 PM