0

I am trying to create pagination for my table that lists the objects returned from my DB as an object. My data structure will look something like:

$scope.myJSONObj = {
    app1: {
      id: 1,
      appName: "appIntegrated1",
      status: "Pending"
    },
    app2: {
      id: 2,
      appName: "appIntegrated2",
      status: "Pending"
    },
    app3: {
      id: 3,
      appName: "appIntegrated3",
      status: "Completed"
    },
    app4: {
      id: 4,
      appName: "appIntegrated4",
      status: "Pending"
    },
    app5: {
      id: 5,
      appName: "appIntegrated5",
      status: "Pending"
    },
    app6: {
      id: 6,
      appName: "appIntegrated6",
      status: "Pending"
    },
    app7: {
      id: 7,
      appName: "appIntegrated7",
      status: "Pending"
    },
    app8: {
      id: 8,
      appName: "appIntegrated8",
      status: "Pending"
    },
    app9: {
      id: 9,
      appName: "appIntegrated9",
      status: "Pending"
    },
    app10: {
      id: 10,
      appName: "appIntegrated10",
      status: "Pending"
    }

I am trying to split my structure in half, and display the first five results. I have a prev/next button, and when I click next, it should display the next 5 results (in this case the last 5). However, for everything to work, I need to be able to split my object, and so far every method I've researched involves arrays, and objects requiring some hack. I was wondering if I was missing something, or I have to create a solution to work with?

4 Answers 4

3

In pure JavaScript :

function getEntries(from, to) {
    var entries = [];
    for(var key in myJSONObj) {
        // extract index after `app`
        // var index = key.substring(3);
        // Better way : extract index using regular expression, so it will match `something1`, `foo2`, `dummy3`
        var index = parseInt(key.replace( /^\D+/g, ''));

        if(index >= from && index <= to) {
            entries.push(myJSONObj[key]);
        }
    }
    return entries;
}

console.log(getEntries(0, 5));
Sign up to request clarification or add additional context in comments.

6 Comments

I didn't see that it wasn't an array, as the root object @stej4n you have a great answer. +1
Edit: a better way to extract index is to use regular expression, so it will match something1, foo2, dummy3 ;)
this is not a perfect solution. it will fail if there is no number in key. eg: {a:{x:1,y:2},b:{x:1,y:2},c:{x:1,y:2},d:{x:1,y:2}}
You are right, a default index (0 for example) can be defined like this : key.replace( /^\D+/g, '') || 0
@ajaiJothi for my app, I can be sure that there will be an int key, but I see your point.
|
1

Try _.chunk

https://lodash.com/docs/4.17.4#chunk

$scope.pages = _.chunk($scope.myJSONObj,5);

$scope.getPage = function( pageIndex ){
return $scope.pages[pageIndex];
}

3 Comments

Thanks for your answer! Sorry, I'm working in a business setting, and am unable to use third party solutions. Without looking at the link, is _.chunk native to Angular? I tried locally and it didn't work.
This is because _.chunk works with Arrays not Objects. You have to use _.pick(object, ['app1', 'app2', 'app3',...]);
Hi @stej4n, could you expand on that in an answer? I'm not sure what you mean. I want to create pagination on objects that I won't be sure what the values coming back are, so I can't hard-code 'app1', 'app2', etc.
1

It's untested - but I wrote a chunk method for you in vanilla JS since you can't use lodash.

    function chunk(obj, chunkSize) {
        var resultArray = [];
        var resultArrayCurrentIndex = 0;
        for (var key in obj) {

            var item = obj[key];
            if (resultArray[resultArrayCurrentIndex].length <= chunkSize) {
                if (!resultArray[resultArrayCurrentIndex]) {
                    resultArray[resultArrayCurrentIndex] = [item];
                } else {
                    resultArray[resultArrayCurrentIndex].push(item)
                }
            } else {
                resultArrayCurrentIndex++
                resultArray[resultArrayCurrentIndex] = [item];
            }
        }

        return resultArray;

    }

Then you can access it like this:

$scope.pages = chunk(yourObject, 5);
$scope.getPage = function(index){
return $scope.pages[index];
}

EDIT - changed it to accept an obj.

1 Comment

Thanks! I'll take a look at your answer in a bit :)
0

Used Object.keys, Array.prototype.slice and Array.prototype.reduce to solve your issue. Hope this helps

angular.module('app',[])
.controller('TestCtrl', function($scope){
$scope.myJSONObj = {"app1":{"id":1,"appName":"appIntegrated1","status":"Pending"},"app2":{"id":2,"appName":"appIntegrated2","status":"Pending"},"app3":{"id":3,"appName":"appIntegrated3","status":"Completed"},"app4":{"id":4,"appName":"appIntegrated4","status":"Pending"},"app5":{"id":5,"appName":"appIntegrated5","status":"Pending"},"app6":{"id":6,"appName":"appIntegrated6","status":"Pending"},"app7":{"id":7,"appName":"appIntegrated7","status":"Pending"},"app8":{"id":8,"appName":"appIntegrated8","status":"Pending"},"app9":{"id":9,"appName":"appIntegrated9","status":"Pending"},"app10":{"id":10,"appName":"appIntegrated10","status":"Pending"}};

$scope.currentPage = 0;
$scope.pageSize = 5;
$scope.totalPage = Math.ceil( Object.keys($scope.myJSONObj).length/$scope.pageSize);
//pageNumber starts from 0 here
$scope.goToPage = function(pageNumber) {
  pageNumber = pageNumber>=0?pageNumber:0;
  var from = pageNumber*$scope.pageSize;
  var to = from + $scope.pageSize;
  return Object.keys($scope.myJSONObj).slice(from,to).reduce(function(a,b){
    a[b] = $scope.myJSONObj[b];
    return a;
  },{});
};

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="TestCtrl">
<button ng-disabled="currentPage===0" ng-click="currentPage = currentPage - 1">prev</button>
<button ng-disabled="currentPage===totalPage-1" ng-click="currentPage = currentPage + 1">next</button>
<b>Page: {{currentPage+1}}/{{totalPage}}</b>
<pre>{{goToPage(currentPage) | json}}</pre>
</div>

Comments

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.