1

I hope you guys can help me.

First off, I know much has been said and written on this subject, and I have been reading up and trying various solutions for the last couple hours, but there is something I am missing.

I also believe it will possibly be a very simple task, so I apologize in advance for my ignorance.

How do I loop though an Array of Objects within Objects in JavaScript?

I have read one should use a for...in loop for arrays, but a simple for loop for objects, but exactly how to loop through and array of objects within object, eludes me.

This is what I am trying to achieve:

I want to display a list of reports (report name) in my UI that matches a specific ReportTemplateTypeId.

To do this, I am trying to loop through my retrieved data (after my data call), to build such a list to display.

The report names I want to display must have a ReportTemplateTypeId == 1

My Retrieved data looks like this: SelectableReportTemplateNames: [{{}},{{}},{{}},{{}}] with an Object within an Object within an Array.

Here is an actual example of the data, with 4 records I would like add to my list:

"SelectableReportTemplateNames": [
    {
        "ReportTemplateId": 1,
        "ReportTemplateName": "Proof of Receipt",
        "ReportTemplatePath": "...rdlc",
        "ReportTemplateType": {
            "ReportTemplateTypeId": 2,
            "ReportTemplateTypeDescription": "Inventory - Proof of Receipt",
            "Id": null
        },
        "Id": "5653781274d4f23d4cbb54b8"
    },
    {
        "ReportTemplateId": 2,
        "ReportTemplateName": "Proof of Transfer",
        "ReportTemplatePath": ".....rdlc",
        "ReportTemplateType": {
            "ReportTemplateTypeId": 3,
            "ReportTemplateTypeDescription": "Inventory - Proof of Transfer",
            "Id": null
        },
        "Id": "5653781274d4f23d4cbb54b9"
    },
    {
        "ReportTemplateId": 11,
        "ReportTemplateName": "All Calls Report",
        "ReportTemplatePath": "....rdlc",
        "ReportTemplateType": {
            "ReportTemplateTypeId": 1,
            "ReportTemplateTypeDescription": "All Calls Report",
            "Id": null
        },
        "Id": "5739a89577801d7f0c10254c"
    },
    {
        "ReportTemplateId": 12,
        "ReportTemplateName": "High Priority Calls Report",
        "ReportTemplatePath": "......rdlc",
        "ReportTemplateType": {
            "ReportTemplateTypeId": 1,
            "ReportTemplateTypeDescription": "High Priority Calls Report",
            "Id": null
        },
        "Id": "5739a89e77801d7f0c10254d"
    },
    {
        "ReportTemplateId": 13,
        "ReportTemplateName": "Call Asset Lines Report",
        "ReportTemplatePath": "......rdlc",
        "ReportTemplateType": {
            "ReportTemplateTypeId": 1,
            "ReportTemplateTypeDescription": "Call Asset Lines Report",
            "Id": null
        },
        "Id": "5739aa7d77801d7f0c10254e"
    },
    {
        "ReportTemplateId": 16,
        "ReportTemplateName": "Daily Status Report",
        "ReportTemplatePath": ".....rdlc",
        "ReportTemplateType": {
            "ReportTemplateTypeId": 1,
            "ReportTemplateTypeDescription": "Daily Status Report",
            "Id": null
        },
        "Id": "5739abb077801d7f0c102552"
    }
],

I thank you greatly in advance!

8
  • "I have read one should use a for...in loop for arrays, but a simple for loop for objects, but exactly how to loop through and array of objects within object, eludes me." No, it's the other way around. Commented May 18, 2016 at 11:34
  • So for clarity you want to loop through this list and print all report names that has ID === 1. Am I right? Commented May 18, 2016 at 11:34
  • As a side note: I am using MongoDB as he DB and AngularJS for my view and controllers. I have tried various Angular filters to display only the filtered data, but get errors. I have tried things like: ng-options="reportSettingsData.SelectableReportTemplateNames | filter:reportType('1') and ng-options="report as reportSettingsData.SelectableReportTemplateNames for report in SelectableReportTemplateNames | filter:ReportTemplateTypeId: 1" and others. Commented May 18, 2016 at 11:37
  • have you tried lodash, it will easy and it will work. _.find(SelectableReportTemplateNames,function(eachReportTemplate){ return eachReportTemplate.ReportTemplateType.ReportTemplateTypeId ==1; }) Commented May 18, 2016 at 11:37
  • @Rajesh That is correct Commented May 18, 2016 at 11:38

8 Answers 8

2

If its just about printing necessary value, you can directly put logic on view.

Updated JSFiddle

View Binding

<select 
  ng-model="test"
  ng-options="item.ReportTemplateId as item.ReportTemplateName for item in data.SelectableReportTemplateNames | filter:isValid">
</select>

Filter function

$scope.isValid = function(o) {
  return o.ReportTemplateType.ReportTemplateTypeId == 1;
}

Demo

function myCtrl($scope) {
  $scope.data = {
    "SelectableReportTemplateNames": [{
      "ReportTemplateId": 1,
      "ReportTemplateName": "Proof of Receipt",
      "ReportTemplatePath": "...rdlc",
      "ReportTemplateType": {
        "ReportTemplateTypeId": 2,
        "ReportTemplateTypeDescription": "Inventory - Proof of Receipt",
        "Id": null
      },
      "Id": "5653781274d4f23d4cbb54b8"
    }, {
      "ReportTemplateId": 2,
      "ReportTemplateName": "Proof of Transfer",
      "ReportTemplatePath": ".....rdlc",
      "ReportTemplateType": {
        "ReportTemplateTypeId": 3,
        "ReportTemplateTypeDescription": "Inventory - Proof of Transfer",
        "Id": null
      },
      "Id": "5653781274d4f23d4cbb54b9"
    }, {
      "ReportTemplateId": 11,
      "ReportTemplateName": "All Calls Report",
      "ReportTemplatePath": "....rdlc",
      "ReportTemplateType": {
        "ReportTemplateTypeId": 1,
        "ReportTemplateTypeDescription": "All Calls Report",
        "Id": null
      },
      "Id": "5739a89577801d7f0c10254c"
    }, {
      "ReportTemplateId": 12,
      "ReportTemplateName": "High Priority Calls Report",
      "ReportTemplatePath": "......rdlc",
      "ReportTemplateType": {
        "ReportTemplateTypeId": 1,
        "ReportTemplateTypeDescription": "High Priority Calls Report",
        "Id": null
      },
      "Id": "5739a89e77801d7f0c10254d"
    }, {
      "ReportTemplateId": 13,
      "ReportTemplateName": "Call Asset Lines Report",
      "ReportTemplatePath": "......rdlc",
      "ReportTemplateType": {
        "ReportTemplateTypeId": 1,
        "ReportTemplateTypeDescription": "Call Asset Lines Report",
        "Id": null
      },
      "Id": "5739aa7d77801d7f0c10254e"
    }, {
      "ReportTemplateId": 16,
      "ReportTemplateName": "Daily Status Report",
      "ReportTemplatePath": ".....rdlc",
      "ReportTemplateType": {
        "ReportTemplateTypeId": 1,
        "ReportTemplateTypeDescription": "Daily Status Report",
        "Id": null
      },
      "Id": "5739abb077801d7f0c102552"
    }]
  }
  
  $scope.isValid = function(o){
  	return o.ReportTemplateType.ReportTemplateTypeId == 1;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<div ng-app>
  <div ng-controller="myCtrl">
    <select 
      ng-model="test"
      ng-options="item.ReportTemplateId as item.ReportTemplateName for item in data.SelectableReportTemplateNames | filter:isValid">
    </select>
  </div>
</div>

Note: This answer assumes ReportTemplateType will always be an object and not an array.

Sign up to request clarification or add additional context in comments.

2 Comments

I love the simplicity of what you are showing. i am using drop down fields for this, using ng-model and ng-options. This does not make use of ng-repeat; how can I implement it however?
Thanks for the help - I am getting the following error: "Error: [IOWA Error] [$parse:syntax] Syntax Error: Token 'as' is an unexpected token at column 23 of the expression [item.ReportTemplateId as item.ReportTemplateName for item in data.SelectableReportTemplateNames | filter:isValid] starting at [as item.ReportTemplateName for item in data.SelectableReportTemplateNames | filter:isValid].
1

You can iterate through it with Array#forEach

var object = { "SelectableReportTemplateNames": [{ "ReportTemplateId": 1, "ReportTemplateName": "Proof of Receipt", "ReportTemplatePath": "...rdlc", "ReportTemplateType": { "ReportTemplateTypeId": 2, "ReportTemplateTypeDescription": "Inventory - Proof of Receipt", "Id": null }, "Id": "5653781274d4f23d4cbb54b8" }, { "ReportTemplateId": 2, "ReportTemplateName": "Proof of Transfer", "ReportTemplatePath": ".....rdlc", "ReportTemplateType": { "ReportTemplateTypeId": 3, "ReportTemplateTypeDescription": "Inventory - Proof of Transfer", "Id": null }, "Id": "5653781274d4f23d4cbb54b9" }, { "ReportTemplateId": 11, "ReportTemplateName": "All Calls Report", "ReportTemplatePath": "....rdlc", "ReportTemplateType": { "ReportTemplateTypeId": 1, "ReportTemplateTypeDescription": "All Calls Report", "Id": null }, "Id": "5739a89577801d7f0c10254c" }, { "ReportTemplateId": 12, "ReportTemplateName": "High Priority Calls Report", "ReportTemplatePath": "......rdlc", "ReportTemplateType": { "ReportTemplateTypeId": 1, "ReportTemplateTypeDescription": "High Priority Calls Report", "Id": null }, "Id": "5739a89e77801d7f0c10254d" }, { "ReportTemplateId": 13, "ReportTemplateName": "Call Asset Lines Report", "ReportTemplatePath": "......rdlc", "ReportTemplateType": { "ReportTemplateTypeId": 1, "ReportTemplateTypeDescription": "Call Asset Lines Report", "Id": null }, "Id": "5739aa7d77801d7f0c10254e" }, { "ReportTemplateId": 16, "ReportTemplateName": "Daily Status Report", "ReportTemplatePath": ".....rdlc", "ReportTemplateType": { "ReportTemplateTypeId": 1, "ReportTemplateTypeDescription": "Daily Status Report", "Id": null }, "Id": "5739abb077801d7f0c102552" }] };

object.SelectableReportTemplateNames.forEach(function (a) {
    if (a.ReportTemplateType.ReportTemplateTypeId === 1) {
        document.write(a.ReportTemplateName + '<br>');
    }
});

2 Comments

Thanks. I am trying to add the item of the match to an array. But it adds empty [objects]. Any idea? See: function getReportNames() { var allReportNames = vm.reportSettingsData; // myArray var selectedReportNames = []; allReportNames.SelectableReportTemplateNames.forEach(function (a) { if (a.ReportTemplateType.ReportTemplateTypeId === 1) { selectedReportNames += a; } }); vm.selectedReportNames = selectedReportNames; return vm.selectedReportNames }
you need to push selectedReportNames.push(a) instead of adding.
1

Step 1: Get the array

var dataArray = data["SelectableReportTemplateNames"];,

assuming your root object is called data.

Step 2: Loop through the array

for (var i = 0; i < dataArray.length; i++) { 
    //do stuff here
}

Step 3: Print data when your predicate holds

for (var i = 0; i < dataArray.length; i++) { 
    if(dataArray[i]["ReportTemplateType"]["ReportTemplateTypeId"] == 1) {
        console.log(dataArray[i]["ReportTemplateName"]);
    }
}

Just to let you know, objects and arrays behave like eachother when it comes to indexing (e.g. data["key"]) and accessing (e.g. data.key)

4 Comments

Thank you for he feedback. I am however trying to get the data based upon the ReportTemplateTypeId (not ReportTemplateId) nested inside the object you are looping through {ReportTemplateType}. Any suggestions?
Oh ok my bad, see my updated answer. It's pretty straightforward tbh
Thanks. I see how it works:) I am trying to add the matching records to an array to display, but only add an empty [Object]. So instead of console.log, how would you add the data to an array? I have tried myArray += dataArray[i] and returning.
adding anything to a list in javascript is done by the .push() function. E.g. var list = [1,3,7]; list.push(5); console.log(list); //prints [1,3,7,5]Of course if you care about the key of the value you can explicitly say list[key] = value
0

If your structure is like that and is not going to change in a long time, you can hardcode your loops:

var outerArray = whateverNameYourVariableHas["SelectableReportTemplateNames"];
for (var objIndex = 0; objIndex < outerArray.length; objIndex++) {
    var currentObject = outerArray[objIndex];
    // handle your objects here

   var templateType - currentObject["ReportTemplateType"];

   for (var templateTypeProperty in templateType) {
       // handle template type properties here.
       // in this loop, templateTyeProperty is a string with the name of the current property.
   }
}

Comments

0

//try this;

$.each(data,SelectableReportTemplateNames,function(a,b){

console.log(b.ReportTemplateId); console.log(b.ReportTemplateName);

});

Comments

0
var myArray = youArrayName["SelectableReportTemplateNames"];

$scope.filteredArray = myArray.filter(function(x){
  return x.ReportTemplateId === 1;
 })
//Filter will be an array containing all that have ReportTemplateId as 1

//Use in ng-repeat like
<p ng-repeat="x in filteredArray">{{x.ReportTemplateName}}</p>

Comments

0

By MongoDb

db.YourCollection.find({ "SelectableReportTemplateNames.ReportTemplateType.ReportTemplateTypeId" : 1});

By JS

var resultTemplate = _.find(SelectableReportTemplateNames,function(eachTemplate){
  return eachTemplate.ReportTemplateType.ReportTemplateTypeId == 1;
})

Comments

0

Look at Mozilla Developer Network - Arrays and Mozilla Developer Network - Objects.

Everything you need for filtering, sorting and general data manipulation can be found there.

EXAMPLES

Assuming that the data is loaded into a handle named data, then the following snippet will give you an array of elements matching your condition:

data.SelectableReportTemplateNames.filter(function (el) {
    return (el.ReportTemplateId === 1);
});
/*OUTPUTS
[{
        "ReportTemplateId" : 1,
        "ReportTemplateName" : "Proof of Receipt",
        "ReportTemplatePath" : "...rdlc",
        "ReportTemplateType" : {
            "ReportTemplateTypeId" : 2,
            "ReportTemplateTypeDescription" : "Inventory - Proof of Receipt",
            "Id" : null
        },
        "Id" : "5653781274d4f23d4cbb54b8"
    }
]
*/

From here you could call forEach to loop through the elements and get output their results:

data.SelectableReportTemplateNames.filter(function (el) {
    return (el.ReportTemplateId === 1);
}).forEach(function (el) {
    console.log(el.ReportTemplateName);
    alert(el.ReportTemplateName);
});
/* ALERTS AND CONSOLE LOGS: "Proof of Receipt" */

EDIT 1

I somehow misread the question, so below is a fixed expression that filters by ReporttemplateTypeId instead of ReportTemplateId:

data.SelectableReportTemplateNames.filter(function (el) {
    return (el.ReportTemplateType.ReportTemplateTypeId === 1);
}).forEach(function (el) {
    console.log(el.ReportTemplateName);
    alert(el.ReportTemplateName);
});
/* OUTPUTS
All Calls Report
High Priority Calls Report
Call Asset Lines Report
Daily Status Report
/*

1 Comment

Thanks for the response. I would like to filter one object deeper. Not ReportTemplateId, but ReporttemplateTypeId === 1. Any suggestions?

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.