My application was built on Angular JS and has a lot AJAX requests on server. For example, in PHP I format output array like as:
$dialog[$userId] = array(
'time' => $key,
'message' => $message['message'],
'name_user' => $info['name']
);
echo json_encode($dialog); die();
But in Angular JS I get not array but object:
549: Objectid_user: "549"message: "Hello"name_user: "Ali Akhmedov"time: 1432070505
Problem that if use ng-repeat
then does not work sorting for object.
Why in PHP I set array but on client get object?
What easy way to convert object to array? Because I have a lot objects on page from AJAX.
To convert an object to an array you use one of three methods: Object.keys() , Object.values() , and Object.entries() . Note that the Object.keys() method has been available since ECMAScript 2015 or ES6, and the Object.values() and Object.entries() have been available since ECMAScript 2017.
To convert an object into an array in Javascript, you can use different types of methods. Some of the methods are Object. keys(), Object. values(),and Object.
assign() method to convert an array of objects to a single object. This merges each object into a single resultant object. The Object. assign() method also merges the properties of one or more objects into a single object.
You don't need to convert object to array in order to iterate over it in ng-repeat
. You can just use the following syntax:
<div ng-repeat="(key, value) in items">{{key}} => {{value}}</div>
Documentation of ngRepeat
.
Unfortunately, this approach will not work with orderBy
filter. To iterate over object properties in specific order, you need to implement your own filter. It may be something like that:
JavaScript
angular.module('app', []).
filter('orderByKey', ['$filter', function($filter) {
return function(items, field, reverse) {
var keys = $filter('orderBy')(Object.keys(items), field, reverse),
obj = {};
keys.forEach(function(key) {
obj[key] = items[key];
});
return obj;
};
}]);
HTML
<div ng-repeat="(key, value) in items | orderByKey:'-'">{{key}} => {{value}}</div>
Plunker
http://plnkr.co/edit/DJo0Y6GaOzSuoi202Hkj?p=preview
However even this approach will work only starting from 1.4.x
, since as it is stated in documentation, AngularJS prior to 1.4.x
will sort object properties in alphabetic order while iterating over them in ngRepeat
.
In order to make it work in Angular 1.3.x
or even 1.2.x
you may perform conversion of object to array of objects, each one of which will contain key
and value
properties. That way you will be able to use it in ngRepeat
in combination with filters including orderBy
. Here is a code:
JavaScript
angular.module('app', []).
factory('srv', ['$http', function($http) {
var items = [],
loaded = false;
return {
getItems: function() {
if(!loaded) { // Lazy loading
$http.get('data.json').success(function(data) { // {key1: 'val1', key2: 'val2'}
Object.keys(data).forEach(function(key) {
items.push({key: key, value: data[key]});
});
});
loaded = true;
}
return items; // [{key: 'key1', value:'val1'}, {key:'key2', value: 'val2'}]
}
};
}]).
controller('ctrl', ['$scope', 'srv', function($scope, srv) {
$scope.items = srv.getItems();
}]);
HTML
<div ng-repeat="item in items | orderBy:'-key'">{{item.key}} => {{item.value}}</div>
Plunker
http://plnkr.co/edit/UXmlm1GKYRZzrOV5pMYT?p=preview
Let's say you have an object like:
$scope.myObj = {type:"Fiat", model:500, color:"white"};
Then, in your angular Controller
you can do something like:
$scope.array = [];
angular.forEach($scope.myObj, function(element) {
$scope.array.push(element);
});
and then in your HTML
<div ng-repeat="obj in array">{{obj}}</div>
Here is a demo plunker
orderBy
is a filter, and filters require an array. So a straightforward solution is to combine it with a toArray
filter. Supposing you want to order your objects using their time
property:
<ol>
<li ng-repeat="value in objectWithValues | toArray | orderBy: 'time'">
{{value.name_user}} said <q>{{value.message}}</q> on {{value.time|date}}
</li>
</ol>
As the toArray
filter is not shipped with AngularJS, you can define one as:
angular.module('ToArrayDemo', [])
.filter('toArray', function() {
return function(obj) {
const result = [];
angular.forEach(obj, function(val) {
result.push(val);
});
return result;
}
});
See https://plnkr.co/edit/E857InfrEGqToW0SvwOh?p=preview
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With