I have a series of arrays, filled with objects - in JSON format. They look something like this:
Group 1
[
{ "name" : "John",
"age" : "31"
},
{ "name" : "Bob",
"age" : "33"
}
]
Group 2
[
{ "name" : "Jim",
"age" : "46"
},
{ "name" : "Harry",
"age" : "23"
}
] // ... and so on ...
In Angular, how can I join the two arrays to form an array of arrays? I'm guessing it's group1.concat(group2), or something like that? I'm not sure where to do it though, would I do this in the controller?
Currently I have a $scope property assigned to each variable, would I make a new $scope property that was a concatenated array of each of these?
And would that be something like:
$scope.allGroups = []
$scope.allGroups = $scope.group1.concat($scope.group2)
// since 'allGroups', 'group1', and 'group2' have all been defined can I do...
allGroups = group1.concat(group2) // ...or does $scope need to be used each time?
My intention is (with the necessary filters) to be able to do an ng-repeat through all groups as they will now all be linked to one $scope variable.
I'm pretty sure that's laiden with errors, but I thought it better to provide some bad code than nothing at all, just so it was more evident what I was trying to do. If there are better approaches (which I'm sure there are), I'm all ears.
Thanks in advance
You're right, array1.concat(array2) is the good method to use.
Now the question is, do you need group1 and group2 to be on your $scope ? Do you need to display them ?
If the answer is no, then you could simply do as follow:
Recover the two arrays and store them in 2 "private" variables
Concat them into a variable set into your $scope
You dont have to set variable into your $scope if you dont display them. It will then look like this:
$scope.allGroups = group1.concat(group2)
Otherwise, no other choice than do like you said:
$scope.allGroups = $scope.group1.concat($scope.group2)
EDIT
If you want an array containing the group1 and group2 arrays, and not only their content, you can simply use the push() method as follow:
$scope.allGroups = [];
$scope.allGroups.push(group1, group2);
If you want to be able to access the concatenated array from your views you have to attach the concatenated array in the $scope object, so you will have to use
$scope.allGroups = $scope.group1.concat($scope.group2)
In the case that you leave var allGroups not attached to the $scope object allGroups will be a local variable to the controller function and will be available only through a closure
You can use concat() to join one array with another.
concat() function returns an array.
Here is the code:
$scope.a = [1,2];
$scope.b = [3,4];
$scope.c = $scope.a.concat($scope.b);
Related
I created an array.
JS code
$scope.type = ["status", "category", "subCategory", "room"];
I want to use array item as variable. I have to create dynamically. Later I will add a dynamic value. For example when I use $scope.type[0]
variable have to be $scope.status How can I do?
You can do that by using the bracket notation.
$scope[$scope.type[0]] = "dynamic value";
To create for every item in array --
$scope.type.forEach(function(value){
$scope[value] = "any dynamic value"
})
Is this your need ?
$scope[$scope.type[0]]
You can try below.
$scope.status = $scope.type[0];
$scope.category= $scope.type[1];
$scope.subCategory= $scope.type[2];
Trying to merge two arrays with some simmilar occurances in two array
here's what i did
var json_dest = [
{
"legID":"12121",
"message":212112
},
{
"legID":"12122",
"message":212112
}
];
var json_src = [
{
"legID":"12121",
"message":212100
},
{
"legID":"12123",
"message":212112
}
];
console.log(angular.merge(json_dest, json_src));
the output is:
[
{
"legID":"12121",
"message":212100
},
{
"legID":"12123",
"message":212112
}
]
it merged the duplicates
but i am missing the other legID "12123"
i need to know how it can be done efficiently ?
and also why is it happening ?
angular.merge is not used to merge arrays but to deeply extend the destination object with enumerable properties of the source object:
Deeply extends the destination object dst by copying own enumerable properties from the src object(s) to dst. You can specify multiple src objects. If you want to preserve original objects, you can do so by passing an empty object as the target:
var object = angular.merge({}, object1, object2) Source
If you just want to combine the two arrays into one you don't need an angular API to do that. Simply use concat:
json_dest = json_dest.concat(json_src);
If you want to remove the duplicates by a certain property, for example legID in your case, you can do that after combining the arrays. There are plenty of resources on how to do that. See for example this question: Remove duplicates from an array of objects in javascript
syntax for merge is
var object = angular.merge({}, obj1, obj2);
it is showing only second element
try using
console.log(angular.merge(dst, src1, src2));
I'm aware that Angular filters can only be applied to arrays, not objects
I'm attempting to include templates added dynamically using the following code. All seems to work well until you see the order
What I would like to have this order:
Create
Book
Address
here is the Plunker
seems like angular will get ng-include by ordering the names according to their name,
so when you use
$scope.templates =
{
_address : 'address.html',
_create : 'create.html',
_book : 'book.html'
};
ordering template according to their names, then _address comes first _book comes second _create comes third
simple approach to solve
$scope.templates =
{
_a_create : 'create.html',
_b_address : 'address.html',
_c_book : 'book.html'
};
here is the Plunker
Instead of using a key-value object, why not use an array? ng-repeat orders the iteration by the index of the iterated object/array.
FORKED DEMO
$scope.templates = [
'create.html',
'book.html',
'address.html'
];
There are other answers that deal with using ng-option with an object formatted like so:
$scope.opts = [
{value: 111, text: '1st' },
{value: 222, text: '2nd' }
];
My question is, can it be done with an object formatted like this?
$scope.opts = [
{'111': '1st'},
{'222': '2nd'}
];
Trying it out doesn't work for me.
Any help?
To clarify:
I'd like the options to be like this <option value="111">1st</option, etc, where the browser shows 1st, and the model returns 111. Can this be done with an array of simplified objects?
No, the answer you point out does not say the same thing as you case. You have an array of objects having a single property with different names; the name of the single property is the key, the value is tha value.
The "object" syntax for the select is about an object, i.e. in your case it should be:
$scope.opts = {
'111': '1st',
'222': '2nd'
};
What you lose with this? No guaranteed iteration order.
In my Backbone app, on my collection I have numerous sorting methods, when rendering the views based on the collection I am currently using a global var set via the route (I do it with a global as other actions add to the collection and I want the last ordering to be used). For example
routes : {
"" : "index",
'/ordering/:order' : 'ordering'
},
ordering : function(theorder) {
ordering = theorder;
listView.render();
},
then in my view
if (typeof ordering === 'undefined') {
d = this.collection.ordered();
}
else if(ordering == 'owners') {
d = this.collection.owners();
}
_.each(d, function(model){
model.set({request : self.model.toJSON()});
var view = new TB_BB.OfferItemView({model : model});
els.push(view.render().el);
});
Where ordered and owners are the 2 ordering methods.
So my first question is, based on routes could someone advice a better way of implementing above? This view gets rendered in multiple places hence me using a global rather than passing a ordered var to the method?
Second question is - I would like to also add some filtering, so lets say I want to sort by 'price' but also do some filtering (lets say by multiple categories id). How could I add a flexible 'route' to deal with filtering.
I guess I could do
routes : {
"" : "index",
'/ordering/:order/:filter1/:filter2' : 'ordering'
},
So the filter1 and filter2 would be the subsequent filtering, but if the filters could be 0 or 100 this will not work. Could anyone offer a solution?
Well, first you should be using Backbone's built-in ability to auto-sort collections. You can take advantage of this by defining a comparator function on your collection. This gives you all kinds of wins right out of the box — for example, the collection will re-sort itself every time you add or remove something from it, based on your comparator. If you want to define multiple sort functions, just define them all as functions and then update comparator when you need to. Then you can ditch that ugly global var.
For your second question, I'm not totally sure what you mean by "if the filters could be 0 or 100 this will not work." If you mean that you'll run into trouble if you don't specifiy all of the filters, then that's true. But you can use a wildcard to fix that. Here's what that might look like:
// your routes look like this:
routes : {
'/ordering/:order/filters/*filters' : 'ordering' // your routes will look like: /ordering/price/filters/filter_one/filter_two/filter_three
},
ordering: function (order, filters) {
filters = filters.split('/'); // creates an array of filters: ['filter_one', 'filter_two', 'filter_three']
listView.render(filters); // pass your filters to the view
}
// listView.render() looks like this:
render: function(filters) {
collection = this.collection;
_.each(filters, function (filter) {
collection = collection.filter(function () {
// your actual filtering code based on what the filter is
});
});
}