the following is a function in an angular controller. "alert (coffee.brand)", or any other part of the array, prints "undefined," which obviously it isn't. The weird part is, undefined prints the correct number of times in the for loop, so it knows the array is populated, it just can't seem to read the data. thoughts? Thanks in advance!
$scope.activate = function(id){
$scope.coffees =
[
{'id': 1,
'brand': 'Folgers',
'name': 'Regular',
'country': 'America',
'reviews': [
{'rating': 3,
'comment': "gross",
'reviewer': "James"
}
]
},
{'id': 2,
'brand': 'Starbucks',
'name': 'Mocha',
'country': 'America',
'reviews': [
{'rating': 7,
'comment': 'insane!',
'reviewer': 'Bob'
},
{'rating': 5,
'comment': 'solid...',
'reviewer': 'Joe'
}
]
}
];
for (coffee in $scope.coffees){
alert (coffee.brand);
if (coffee.id == id){
$scope.currCoffee = coffee;
alert("here")
alert ($scope.currCoffee.id);
}
}
};
You are using the for in loop incorrectly. It does not iterate over elements in an array, but property names of an object. In your case, as you are using an implicitly numerically indexed array, it would be better to use a normal for loop, like so:
for (var i = 0; i < $scope.coffees.length; i++) {
var coffee = $scope.coffees[i];
alert (coffee.brand);
if (coffee.id == id){
$scope.currCoffee = coffee;
alert("here")
alert ($scope.currCoffee.id);
}
}
See the documentation over at MDN for more information about the for in loop.
You should update the for loop to
for (var i = 0; i < $scope.coffees.length; i++) {
and retrieve values like
alert($scope.coffees[i].brand);
For reference - http://plnkr.co/edit/bmuJmJO94mEzGuB3uF0K?p=preview
coffee is key not the object itself, so go like $scope.coffees[coffee].
For more information
for...in loop
It iterates enumerable own and enumerable inherited properties.
Related
I am fetching some json, but i want to add a key value pair to each object inside the array.
What i want is to add a key value pair to each object inside students array
You can do something like this:
var students = [ { city: 'California', company: 'ABC'}, { city: 'LA', company: 'PQR'}, { city: 'Mumbai', company: 'XYZ'}];
students.forEach((obj) => {
obj['email']= 'abc#xyz.com';
console.log(obj);
});
// Final Output
console.log(students);
I would suggest you simply use a for loop for each element in your array and since it's JSON simply specify a new "key = value" inside the current element.
edit : here's an example :
var entreprises = [
{id: 33, uuid: "3d103130-ae0d-11e9-8e6c-dfb1a3a5afce", nom: "test", adresse: "test", ville: "tes" },
{id: 34, uuid: "81524090-ae0d-11e9-8894-2326c7695f11", nom: "test2", adresse: "test2", ville: "test2"}];
for (let i = 0; i < entreprises.length; i++) {
entreprises[i].key = "value";
}
Start by iterating through the students array using either a foreach or standard for loop. This will give you access to each of the students, one by one. Since each of the students is an object, you will have to use either bracket or dot notation to store this new key,value pair. Here is an article that will help you determine which strategy to use for accessing keys and storing key,value pairs: Bracket notation vs Dot notation
Note: If the key you are adding already exists, you will be overriding the previous value.
For loop
for (let i = 0; i < students.length; i++) {
const student = students[i];
student[<key>] = <value>;
}
Foreach
students.forEach(student => {
student[<key>] = <value>;
});
I've got an array of objects
var myArray = [{'id':'1','value':'firstValue'},{'id':'1','value':'secondValue'}, etc.]
I want to be able to extend the array later on in the code, so that I will have
var myArray = [{'id':'1','value':'firstValue', 'anothervalue':'anotherFirstValue'},{'id':'1','value':'secondValue', 'anothervalue':'anotherSecondValue'}, etc.]
Is there a way to do it without redefining myArray?
You can map the array, and add to each object:
var myArray = [{
'id': '1',
'value': 'firstValue'
}, {
'id': '1',
'value': 'secondValue'
}];
//later on
myArray = myArray.map(function(obj) {
obj.anothervalue = 'anotherFirstValue';
return obj;
});
console.log(myArray);
I need to detect an object in an array with its Id.
My first array looks like that:
{ [id: 9, name: 'abc'], [id: 2, name 'def'], [id: 40, name: 'gh'] } (Id & name),
while that other array is:
{ [class: 'physics', Tid: 9], [class: 'computer science', Tid: 9], [class: 'Biology', Tid: 40] }.
I need to match the parameter "name" from the first array by its ID to its "class" (for example, "physics" relates to Tid=9 which is "abc" and "Biology" relates to Tid=40 which is "gh").
How can I elegantly do so without changing the way the data comes? (It comes from a database with ASP.NET web service in JSON)
You could use $http.get() which has success and error callback functions, which returns a promise object. Using this, you can setup a condition to map the id and get your desired result.
Something like this.
var myObject1 = {};
var myArray1 = [];
var myObject2 = {};
var myArray2 = [];
$http.get('json-file')
.success(function(data)) {
myObject1.myArray1 = data;
}
$http.get('json-file')
.success(function(data)) {
myObject2.myArray2 = data;
}
/* inside a loop if required */
if (myObject1.myArray1[index].id == myObject2.myArray2[index].Tid) {
/* perform logic */
}
This code would be present inside a service or a controller.
Haven't tested it so unsure of the syntax but promise objects are the way to go.
Hope this helps.
This returns an array of arrays. Each array in the array contains two objects matched by id === Tid. As far as I can tell that's what you want.
(Note that I think you provided broken sample arrays, I adjusted and scrambled the numbers around so you could see it work more clearly).
var arr1 = [ {id: 9, name: 'abc'}, {id: 2, name: 'def'}, {id: 40, name: 'gh'} ];
var arr2 = [ {class: 'physics', Tid: 2}, {class: 'computer science', Tid: 40}, {class: 'Biology', Tid: 9} ];
var arrFinal = arr1.map ( function ( d ) {
var matched = arr2.find ( function ( obj ) {
return obj.Tid === d.id;
} );
return [ d, matched ];
} );
If you iterate arrFinal you'll see it contains the matched objects.
I'm using $.getJSON to pull some data from an data source and the result comes in as JSON, but it's in this format (as it comes from a table):
result {
0: Array {
0: 'First Name',
1: 'Last Name',
2: 'City',
3: 'State'
}
1: Array {
0: 'John',
1: 'Doe',
2: 'Portland',
3: 'Oregon'
}
2: Array {
0: 'Jane',
1: 'Doe',
2: 'Seattle',
3: 'Washington'
}
}
I need to get that data into something that looks more like this:
Object {
'First Name': 'John', 'Jane'
'Last Name': 'Doe', 'Doe'
'City': 'Portland', 'Seattle'
'State': 'Oregon', 'Washington'
}
I thought that I would just put these into a few $.each() loops but I can't seem to get an object with the first array's values as the keys and the matching values as items in an array assigned to that key. I've tried something like this:
var tmpArray = [];
var labelKeys = [];
$.each(result, function(key, val){
if (key < 1){
$.each(val, function(labelKey, labelVal){
labelKeys.push(labelVal);
}
} else {
for (var i=0; i<labelKeys.length;i++){
tmpArray[labelKeys[i]].push(val[i]);
}
}
}
That doesn't work and I get an undefined error for push().
I can separate all the arrays out into their own arrays and get them out to the console, but I can't figure out how to push data to an object or an array using a key value.
How do I push values to an object so that I can just loop through the arrays and group the objects at the same numbered location and assign it to a key that's at the same location in the first array?
You can't call .push() on tmpArray[labelKeys[i]] because it doesn't exist yet. You need to add that key to the object, before trying to call .push().
// this needs to be an object
// arrays can only have numeric keys
var tmpArray = {};
var labelKeys = [];
$.each(result, function(key, val){
if (key < 1){
$.each(val, function(labelKey, labelVal){
labelKeys.push(labelVal);
// Create an array for this label
tmpArray[labelVal] = [];
});
} else {
for (var i=0; i<labelKeys.length;i++){
tmpArray[labelKeys[i]].push(val[i]);
}
}
});
So I have two data sets. The mainData being the data I want to push to and display as the main data set.
// data set 1
var mainData = [{name: "david", views: 2}, {name: "andrew", views: 2}];
// data set 2
var newData = [{name: "andrew", views: 4}, {name: "david", views: 4}, {name: "chris", views: 2}];
The second data set is new or incoming data which I want to do one of two things with. I want to search through the main data set and see if any keys match, if so I just want to add views to the object with the same name. If the name key doesn't match any object in the mainData I want to then push that object to mainData.
My final mainData should look like this:
[{name: "david", views: 6}, {name: "andrew", views: 6}, {name: "chris", views: 2}]
Notice how david and andrew now have values of 6 while chris did not match any objects and was simply pushed. What is the most effiecient way of acheiving this in pure Javascript?
If you want to empty newData during processing do:
while (newData.length) {
var nd = newData.shift(), nam = nd.name, vie = nd.view;
if (!mainData.some(function(md) {
if (md.name === nam) {md.view += vie; return true;}
})) mainData.push(nd);
}
else if the objects in newData shall stay there do
newData.forEach(function(nd) {
var nam = nd.nam, vie = nd.view;
if (!mainData.some(function(md) {
if (md.name === nam) {md.view += vie; return true;}
})) mainData.push(nd);
});
In both cases mainData.some() iterates over mainData. Its callback function checks at each step whether the name-properties are identic. If so, the view-properties are added, the callback returns true (= "matching names found") and iteration is stopped. Otherwise the callback returns nothing and iteration goes on. Since some() is inside an negated condition, mainData.push() happens only if some() does not find a match.
Array.forEach() and some() are very fast. If they are not available, you have to use for-loops with less efficiency.