Unraveling nested elements with the array map() method in Angular2 and Typescript: Fixing the issue of undefined property reference while mapping

Hey there! I'm currently working with Angular 4 and I have a piece of code that parses data from an API into a TypeScript array of rows. It's important to note that the code functions properly if elements like 'item.tceCampRun' and 'item.tceCommTreeDetail' are present.

However, when one of these elements, such as 'item.tceCommTreeDetail', is missing, I encounter the following error: TypeError: Cannot read property 'map' of undefined.

I was wondering what would be the most effective approach to handle a nested object in this situation?

 private handleGetCamp(data: Response) {
    if (data.status === 200) {
      // this.tceCamp = data.json();
      // this.firstTceCamp = this.tceCamp[0];

      let other = []; // your other array...
      let j = 1;
      let run = 999000;
      let runheader = true;
      let runheaderid = 1;

      data.json().map(item => {
          j++;
          runheader = true;
          return {
              id: j,
              rowtype: 'camp',
              expanded: false,
              cells: [{ cid: 1, text: item.name }, { cid: 2, text: item.dailyStartTime }, { cid: 3, text: item.dailyEndTime }, { cid: 4, text: item.scriptId }, { cid: 14 }],
              rows:[{
                id: run++,
                pid: j,
                header: true,
                rowtype: 'run',
                expanded: false,
                cells: [{cid: 1, text: 'Runs', header: false},
                  {cid: 2, text: 'Created', header: true},
                  {cid: 3, text: 'Modified', header: true},
                  {cid: 4, text: 'Camp', header: true},
                  {cid: 12, text: ' ', header: true},
                  {cid: 13, text: ' ', header: true}],
                rows:
                  item.tceCampRun.map(item2 => {
                    return {
                      id: run++,
                      mypid: runheaderid,
                      pid: runheaderid,
                      rowtype: 'run',
                      expanded: false,
                      cells: [{cid: 1, text: item2.name}, {cid: 2, text: 'c 2'}, {cid: 3, text: 'c 3'}, {
                        cid: 4,
                        text: item2.id
                      }, {cid: 14}]
                    }
                  })
              },
                {
                id: run++,
                pid: j,
                header: true,
                expanded: false,
                rowtype: 'InteractiveScript',
                cells: [{ cid: 1, text: 'Interactive Script', header: false },
                  { cid: 2, text: 'Response', header: true },
                  { cid: 3, text: 'Action', header: true },
                  { cid: 4, text: 'Action Value', header: true },
                  { cid: 12, header: true  },
                  { cid: 13, header: true }],
                rows:
                  item.tceCommTreeDetail.map(item3 => {
                    return {
                      id: run++,
                      mypid: runheaderid,
                      pid: runheaderid,
                      rowtype: 'run',
                      expanded: false,
                      cells: [{cid: 1, text: item3.name}, {cid: 2, text: 'c 2'}, {cid: 3, text: 'c 3'}, {
                        cid: 4,
                        text: item3.id
                      }, {cid: 14}]
                    }
                  })

                }
              ]

          }
      }).forEach(item => other.push(item));

The format of the nested rows should resemble this image: https://i.stack.imgur.com/yJXez.png

Answer №1

For increased readability and clarity, rather than structuring your code like this:

return {
  // ...everything under the sun...
  // ...all in one long, long list...
};

It is advisable to break down the big object into smaller parts and assign them to variables before the return statement.

Here's a better approach:

if (item.tceCommTreeDetail) {
  rows = item.tceCommTreeDetail.map(item3 => {...
  ...
}
else {
  rows = []; // You can use null or any other value if item.tceCommTreeDetail is not defined.
}

Finally:

return {
  // ...
  rows: rows,
  // ...
};

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

Choose Your Preferences When the Page Loads

I have a dropdown menu where I can select multiple options at once without checkboxes. When the page loads, I want all of the options to be pre-selected by default. I am aware that I can use $(document).ready() to trigger actions after the page has load ...

Evaluate the functionality of an Angular controller method that interacts with the Document Object Model (

We currently have an AngularJS controller that contains the following function: $scope.testMe = function() { return $('#test'); } So, how can we effectively test this function? We attempted a Karma test as shown below: describe(' ...

What is the best way to implement a dialog box that displays a website within it, all while keeping my SharePoint site running in the background?

For a while now, I've been working on SharePoint Online and trying to troubleshoot an issue without success. That's why I'm considering starting over with a specific section of my SP site from scratch. My current project involves creating a ...

Adjust the content of an iframe based on the size of the screen

Hi there, I'm currently facing an issue with an ad that can't be resized. The support team suggested using two different ads - one for mobile and one for desktop. The dimensions of the ads are 720 x 90 and 300 x 100. I would like the ad to automa ...

add the string to the chat messages array in the observable

Currently, I am in the process of developing a chat application and my goal is to showcase the user's messages in the chatroom, referred to as the feed in this project. I have already implemented a function called getMessages() that displays all exist ...

What is the best way to transform a string into React components that can be displayed on the screen?

Stored in my database are strings that contain partial HTML content, as shown below: “Intro<br /><br />Paragraph 1<br /><br />Paragraph 2” If I want to display this string within a new <p> element, what is a straightforwa ...

Trigger the click event on the ul element instead of the li element using jQuery

Is there a way to make the click event only affect ul tags and not all li elements using jQuery? <!-- HTML --> <ul class="wrap"> <li>test1</li> <li>test2</li> <li>test3</li> </ul> I attemp ...

"Protractor's browser.wait in Angular application fails to wait for the element to be visible

I am encountering an issue with the wrong login message. I am using async spec along with browser.wait to wait for the element to appear in the DOM, but it is not functioning as expected. Instead of waiting for the specified timeout if the element is not p ...

Please ensure that the table is empty before reloading data into it

I am facing an issue while binding data from the database. The data is being bound every 5 seconds, however, it does not clear the previous data and keeps accumulating. Instead of displaying just 3 rows when there are 3 in the database, it adds 3 rows ev ...

Creating evenly spaced PHP-generated divs without utilizing flexbox

My goal is to display images randomly from my image file using PHP, which is working fine. However, I am facing an issue with spacing the images evenly to fill the width of my site. This is how it currently appears: https://i.stack.imgur.com/AzKTK.png I ...

how can I pass a group of values as an argument in math.sum function?

Using math.js for convenience, I was intrigued if I could utilize the math.sum method to calculate the sum of a collection of input values. For example, something along the lines of: Here's a snippet of code to help visualize my concept: $(documen ...

The hyperlink element has been added but is not clickable

I'm attempting to incorporate a download feature into my webpage using Greasemonkey. Despite successfully adding the new div element to the page, I am encountering an issue where the download window does not open as expected. var iDiv = document.crea ...

What is the process for moving information between files?

I have two files which are named as, employee-rates-controller.ts: private load() { return this.entityService .load(this.$scope.projectRevisionUid) .then(resp => { localStorage.removeItem('employeerates'); this.$ ...

I am encountering a "TypeError: topics.forEach is not a function" error when attempting to retrieve metadata for topics using my kafkajs client in Node.js/express.js. Can anyone help me understand why

I am attempting to retrieve the metadata of my Kafka brokers' topics using the kafkajs admin client within my Node.js + express.js server. Here is the content of my index.js file, serving as the main entrypoint for npm: 'use strict'; cons ...

Is it possible to store Socket.IO responses in a cache for quicker retrieval?

Consider this scenario where I have a websocket implementation shown below: let itemsArray = []; function fetchData() { itemsArray = await db.query(`SELECT * FROM Items`); } function emitData() { io.sockets.in("room_foo").emit("data", JSON.stringify ...

Updating a boolean value when the checkbox is selected

Hey there! I'm currently working on a project using Angular and have a collection of elements that can be checked, which you can check out here. In terms of my business logic: stateChange(event: any, illRecipe: Attendance){ var state: State = { ...

Exploring Vue.js: Navigating through child components from parent component

I currently have 3 components in my project: Form, Card, and Button. Let's start with the Button.vue component: <template> <div> <slot v-bind="{ text }"> <button>{{ text }}</button> </slot> ...

What is the best way to create a fixed footer in Next.js using React?

I'm looking to create a fixed footer that will stay at the bottom of the page if there isn't enough content to fill it. I've been researching ways to achieve this using CSS, but many of the methods don't easily translate to React/Next.j ...

How to Share Angular Modules Between Two Projects with Ivy Compilation Necessity

Query: I am faced with the challenge of sharing common modules between two Angular projects, one of which requires full Ivy compilation to function properly. To manage these shared resources, we have set up a private GitHub NPM repository. However, becaus ...

Using Selenium in Java, one can wait for a JavaScript event (such as onchange) to finish before proceeding

When a group of interconnected input fields have an onchange event, the values in some fields are updated correctly while others are not due to interference from the onchange event. Once the onchange event is triggered on a field, it initiates a process t ...