Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort JSON data in ng-repeat?

I am getting a server response and binding these data to view using ng-repeat. Now I want to sort these data by priceList and name. I am able to sort name using orderBy, but not with priceList. I want to sort the products based on priceList. Sorting with name will change the order of list while sorting by priceList will effect only the order of products of each category. It will effect the order of displayed category. Please help me resolve this.
My code:

<div ng-controller="Ctrl">
    <pre>Sorting predicate = {{predicate}};</pre>
    <hr/>
    <table class="friend">
        <tr>
            <th><a href="" ng-click="predicate = 'name'; reverse=false">Name</a>
            </th>
            <th><a href="" ng-click="predicate = 'priceList'>price</a></th>
        </tr>

    </table>


<div ng-repeat="data in _JSON[0].categories | orderBy:predicate">
       <div ng-repeat="vals in data.itemTypeResults |orderBy:'partTerminologyName'" id="{{vals.partTerminologyName}}">
`<h4 style="background-color: gray">{{vals.partTerminologyName}} : Position :{{vals.position}}</h4>`<br>


<div ng-repeat="val in vals.products">
    <b> Quantity:{{val[0].perCarQty}}</b><br>
    <b> part:{{val[0].partNo}}</b><br>
    <b>sku:{{val[0].sku}}</b><br>
    <b> qtyInStock:{{val[0].qtyInStock}}</b><br>
    <b> priceList:{{val[0].priceList}}</b><br>
    <b>priceSave:{{val[0].priceSave}}</b><br>
    <b> qtyDC:{{val[0].qtyDC}}</b><br>
    <b> qtyNetwork:{{val[0].qtyNetwork}}</b><br>
    <b> priceCore:{{val[0].priceCore}}</b><br>
        </div>
</div>      
    </div>

JS:

$scope._JSON = [
        {"categories":
            [
                {"id":14061,"name":"Drive Belts",
                    "itemTypeResults":[
                        {"partTerminologyName":"Serp. Belt",
                            "position":"Main Drive",
                            "products":{
                                "5060635":[
                                    {"perCarQty":2,"partNo":"5060635",
                                    "sku":"20060904","qtyInStock":2,"qtyNetwork":4,
                                    "qtyDC":6,"priceList":19.15,"priceSave":3.29,
                                    "priceCore":10.0}
                                ],
                                "635K6":[
                                    {"perCarQty":9,"partNo":"635K6",
                                        "sku":"10062449","qtyInStock":2,"qtyNetwork":4,
                                        "qtyDC":6,"priceList":18.15,"priceSave":3.21,"priceCore":10.0}
                                ]
                            }
                        }
                    ]
                },
                {"id":2610,"name":"Drive Belt Tensioners, Idlers, Pulleys & Components",
                    "itemTypeResults":[
                        {"partTerminologyName":"Drive Belt Tensioner Assembly",
                        "position":"N/A",
                            "products":{
                                "950489A":[
                                    {"perCarQty":4,"partNo":"950489A",
                                        "sku":"10150833","qtyInStock":2,"qtyNetwork":4,
                                        "qtyDC":6,"priceList":18.15,"priceSave":3.21,"priceCore":10.0
                                    }
                                ]
                            }},
                        {"partTerminologyName":"Drive Belt Idler Pulley","position":"N/A",
                            "products":{
                                "89161":[
                                    {"perCarQty":1,"partNo":"89161",
                                    "sku":"99995959","qtyInStock":2,"qtyNetwork":4,
                                    "qtyDC":6,"priceList":17.15,"priceSave":3.21,"priceCore":10.0}
                                ],
                                "951373A":[
                                    {"perCarQty":2,"partNo":"951373A","pla":"LTN",
                                    "plaName":"Litens",
                                    "sku":"10150926","qtyInStock":2,"qtyNetwork":4,
                                        "qtyDC":6,"priceList":18.15,"priceSave":3.21,"priceCore":10.0}
                                ]
                            }
                        }
                    ]
                }
            ]
        }
    ];
    $scope.predicate = '';

Fiddle: Fiddle

like image 370
Ved Avatar asked Dec 22 '15 17:12

Ved


1 Answers

You might need to define a very good sorter function, or sort your products before they are interpreted by ng-repeat. I've created sorter function using underscore.js (or lodash).

You can checkout the demo (or the updated demo). Products are first sorted by category and then sorted by price in every category.

<!-- in html -->
<button ng-click="sortFn=sortByPrice">Sort By Price</button>
<button ng-click="sortFn=doNotSort">Do not Sort</button>
...
<div ng-repeat="val in sortFn(vals.products)">
  ...
// in js
$scope.sortByPrice = function(products) {
  return _.sortBy(products, function(product) {
    return product.length > 0 ? product[0].priceList : 0;
  });
};

$scope.doNotSort = function(products) {
  return products;
};

$scope.sortFn = $scope.doNotSort; // do not sort by default

BTW: You are directly calling val[0], which is very dangerous, if the product does not contain any elements, your code will break. My code won't ;-)


Update 1

The author asks me for a more pure Angular way solution.

Here is my answer: I think my solution is exactly in Angular way. Usually you can implement a filter (similar to orderBy) which wraps my sortByPrice. Why I don't do that, because you have ng-click to switch your order filter. I'd rather put control logic into a controller, not as pieces into view. This will be harder to maintain, when your project keeps growing.


Update 2

Okay, to make the +50 worthy, here is the filter version you want, (typed with my brain compiler) Please check in fiddle

like image 145
stanleyxu2005 Avatar answered Sep 30 '22 08:09

stanleyxu2005