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.
    – Geeky Guy
    CommentedMay 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?
    – Rajesh
    CommentedMay 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.
    – onmyway
    CommentedMay 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; })CommentedMay 18, 2016 at 11:37
  • @Rajesh That is correct
    – onmyway
    CommentedMay 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.

2
  • 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?
    – onmyway
    CommentedMay 18, 2016 at 12:20
  • 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].
    – onmyway
    CommentedMay 18, 2016 at 13:01
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
  • 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 }
    – onmyway
    CommentedMay 18, 2016 at 13:57
  • 1
    you need to push selectedReportNames.push(a) instead of adding.CommentedMay 18, 2016 at 14:12
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
  • 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?
    – onmyway
    CommentedMay 18, 2016 at 13:18
  • Oh ok my bad, see my updated answer. It's pretty straightforward tbh
    – Glubus
    CommentedMay 18, 2016 at 13:48
  • 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.
    – onmyway
    CommentedMay 18, 2016 at 14:12
  • 1
    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
    – Glubus
    CommentedMay 18, 2016 at 14:18
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. } } 
    0

    //try this;

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

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

    });

      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> 
        0

        By MongoDb

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

        By JS

        var resultTemplate = _.find(SelectableReportTemplateNames,function(eachTemplate){ return eachTemplate.ReportTemplateType.ReportTemplateTypeId == 1; }) 
          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
          • Thanks for the response. I would like to filter one object deeper. Not ReportTemplateId, but ReporttemplateTypeId === 1. Any suggestions?
            – onmyway
            CommentedMay 18, 2016 at 13:10

          Start asking to get answers

          Find the answer to your question by asking.

          Ask question

          Explore related questions

          See similar questions with these tags.