Traverse an Array of Objects nested within Objects using JavaScript

I am seeking assistance with a JavaScript problem.

Despite researching and trying different solutions for hours, I am still missing something crucial.

It seems like a simple task, so please forgive my lack of knowledge.

How can I loop through an Array of Objects within Objects in JavaScript?

I have learned that one should use a for...in loop for arrays and a simple for loop for objects. However, I am struggling to figure out how to loop through an array of objects within an object.

Here is my goal:

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

To achieve this, I need to iterate through my retrieved data after making a data call to build the list.

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

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

Below is an example of the data, featuring 4 records I would like to 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"
    }
],

Your help is greatly appreciated!

Answer №1

If you only need to print certain values, you can apply the logic directly in the view.

Check out the updated JSFiddle here

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 solution assumes that ReportTemplateType will always be an object and not an array.

Answer №2

To access each element, you can use the Array#forEach method.

var data = { "Items": [{ "ItemId": 1, "ItemName": "Apple", "ItemCategory": "Fruit", "Price": 1.99 }, { "ItemId": 2, "ItemName": "Banana", "ItemCategory": "Fruit", "Price": 0.99 }, { "ItemId": 3, "ItemName": "Carrot","ItemCategory": "Vegetable", "Price": 0.75	}]};
data.Items.forEach(function (item) {
    if (item.ItemCategory === 'Fruit') {
        console.log(item.ItemName + '-' + item.Price);
    }
});

Answer №3

Step 1: Obtain the array

let dataEntries = data["SelectableReportTemplateNames"];
,

assuming your main object is named data.

Step 2: Iterate through the array

for (let j = 0; j < dataEntries.length; j++) { 
    //perform actions here
}

Step 3: Display data based on conditions

for (let k = 0; k < dataEntries.length; k++) { 
    if(dataEntries[k]["ReportTemplateType"]["ReportTemplateTypeId"] == 1) {
        console.log(dataEntries[k]["ReportTemplateName"]);
    }
}

Keep in mind, objects and arrays can be accessed similarly through indexing (e.g. data["key"]) and direct access (e.g. data.key)

Answer №4

If your structure remains constant for a while, it may be beneficial to hardcode your loops:

let data = myData["SelectableReportTemplateNames"];
for (let i = 0; i < data.length; i++) {
    let currentObject = data[i];
    // handle objects here

   let templateType - currentObject["ReportTemplateType"];

   for (let property in templateType) {
       // handle properties of template type.
       // property variable contains the name of the current property in this loop.
   }
}

Answer №5

//test this out;

$.each(data,DisplayableReportModels,function(x,y){

console.log(y.ReportModelId); console.log(y.ReportModelName);

});

Answer №6

const templateArray = yourArrayName["SelectableReportTemplateNames"];

$scope.filteredTemplates = templateArray.filter(function(template){
  return template.ReportTemplateId === 1;
 })
//The filteredTemplates array will now contain all templates with ReportTemplateId of 1

//To use in ng-repeat:
<p ng-repeat="template in filteredTemplates">{{template.ReportTemplateName}}</p>

Answer №7

Using MongoDb

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

Implemented in JavaScript

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

Answer №8

Check out the Mozilla Developer Network - Arrays and Mozilla Developer Network - Objects for all your data manipulation needs.

TIPS

If you have your data stored in a variable called data, you can use the following code snippet to filter elements based on your condition:

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

You can then use forEach to iterate through the filtered elements and display 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" */

UPDATE 1

I misunderstood the question initially, here is the corrected code 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);
});
/* OUTPUT
All Calls Report
High Priority Calls Report
Call Asset Lines Report
Daily Status Report
/*

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combining Multiple NodeLists in Javascript

Initially, I was seeking a sophisticated method to replicate the functionality of Array.concat() on the results of the getElementsByTagName function in older browsers like IE because it appeared that concat wasn't supported. However, as it turns out, ...

Replace Jade script with block override

Having trouble overriding a Jade script. tag, nothing seems to work. Here is the code snippet: Layout.jade block foot footer.container#footer .row .twelve.columns All rights reserved. &copy; 2015 Pet Feeder block scripts ...

Creating an Ajax script to show a comment or information box when a webpage fails to load

Below is the code snippet: <script> function AjaxLoadFWs() { var sPath = window.location.pathname; var sPage = sPath.substring(sPath.lastIndexOf('/') + 1); $('#overviewfw').load("http://test.com/test. ...

Struggling to access the `this` keyword within a callback function in an Angular Controller class using ES

Take a look at this sample class: class LoginController{ constructor(authService,$timeout,$state){ let vm = this; this.loading = false; this._authService = authService; this._$timeout = $timeout; this._$state = ...

Unlocking route access through server-side Firebase authentication

I have integrated sessionStorage and firebase authentication for user email and password in my project. Currently, I am facing an issue in my server.js where I need to prevent access to a route if the user is not logged in, and instead redirect them to th ...

Track the reading progress of each article on a single page with individual progress bars

Is it possible to customize the progress bar for each individual article on a single page? I attempted to use code from (Reading Position Indicator based on DIV instead of the whole page), but it only seems to work with the first div. $(doc ...

Ensure AngularJS creates a controller just once

In my search for a way to create a controller only once, I have not come across any satisfactory solutions. I have discovered some alternative approaches: Creating a controller list in $rootScope and adding newly created controllers to it Developing a m ...

Extract the JSON value from a JavaScript variable using the index value function

Is there a way to modify the index value function to fetch the gb value of the "see": 8 variable within the "val": "West" group? Could utilizing an array be a solution for this scenario? Although the correct value for the gamesBack of the val.see == 8 is ...

Implementing Secure Authentication in a Fresh MEANJS Module

Currently facing an issue in the MEAN stack related to authentication. Recently developed a new module called "Wallet" and below is its model structure: var WalletSchema = new Schema({ created: { type: Date, default: Date.now }, bitcoinAddr ...

Difficulty Establishing a Connection with SQL Server Using TypeORM

My local machine is running an SQL Server instance, but I'm encountering an error when trying to connect a database from TypeORM. The error message reads: originalError: ConnectionError: Failed to connect to localhost:1433 - Could not connect (seque ...

Should I avoid using `v-on` in my code?

Many experts suggest avoiding the use of HTML's onclick attribute as it can reduce code readability. Instead, they recommend creating an event listener in a separate script.js file. What are your thoughts on using v-on:click? Is it also considered bad ...

Best practice for placing business logic following an $.ajax request

Initially, I had put all my sorcery within the success function, but then I discovered that one could add done(...) after the call (and supposedly there's a ready option too). Where should I place the most effective location for performing these magi ...

Prevent selection of weekends and dates in the past using AngularJS

I have been trying to insert a date picker text box using the code below: <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script> <script> function MainController($scope) { $scope.date = ne ...

Exploring color gradation using GLSL shaders in WebGL

I want to achieve a black color in the center of my disk with a gradient effect towards the outer edges. However, when I use the GLSL code "gl_FragColor = vec4( vec3( vUv, 0.17 ), 1. );" I encounter some issues. varying vec2 vUv; void main() { vUv ...

Managing channel permissions in Discord.js

Having trouble creating a new channel and need some guidance. I am trying to use the following code: message.guild.channels.create('channel name', { type: 'voice', permissionOverwrites: [ { id: some_id, deny: [&ap ...

Building Relationships in LoopBack version 4 Using the Include Key

Learn more about HasMany relation in LoopBack 4 here After following the necessary steps, I attempted to retrieve data using the include option but encountered a 500 error. 500 Error: Invalid "filter.include" entries: {"relation":"ranks"} My objective i ...

When using jQuery.load(), images echoed through Ajax are not loading properly

Experiencing difficulties with utilizing JQuery's .load() function to load images and create a dynamic slot machine. The following is the initial HTML code that will be loaded: index.php <p id='slotContainer'> <?php ...

Validation error detected in the textbox fields

I have incorporated Bootstrap into my application. For a specific functionality, I am dynamically creating dropdown and textbox controls based on a count and implementing validation. However, the validation seems to be malfunctioning only for the textbox ...

Determine the daily volume of emails sent from the "no-reply email" address using the Nodemailer library

Our company currently utilizes Nodemailer for internal email communication. Lately, we have been encountering issues with exceeding our daily SMTP relays, resulting in some emails failing to send. To investigate further, I have been tasked with monitoring ...

Append a constant string to the conclusion of the route parameter

Using React Router v6.4.1, I am aiming for a consistent conclusion to a series of dynamic routes. Specifically, I want my product detail routes to always end with "-product". For example, if the path is "/shaver-900-product", it should activate my Produc ...