How to Retrieve Grandparent Component Attributes in Angular Using Grandchild Components

I am constructing an Angular application and facing the challenge of accessing a property of Component 1 within Component 3. In this scenario, the relationship is described as grandparent-grandchild.

Successfully establishing communication between parent/child components directly, such as from Component 1 to Component 2 and from Component 2 to Component 3 (Component 3 being the child of Component 2 and Component 2 the child of Component 1). The requirement is for one-way communication, specifically accessing properties from (grand)parent-components in the child-component.

Take a look at the application structure provided below, showcasing the usage of shared services.

Component 1.ts

import { Component, OnInit } from '@angular/core'
import { StrategyService } from './shared/strategy.service'

@Component({
    selector: 'strategies-list',
    templateUrl: './strategies-list.component.html'        
})

export class StrategiesListComponent implements OnInit {
    strategies:any[]
    constructor(private strategyService: StrategyService) {

    }

    ngOnInit() {
        this.strategies = this.strategyService.getStrategies()
    }

}

Component 1.html

<div>
<h1>Strategies</h1>
<hr/>
<strategy-thumbnail *ngFor = "let strategy of strategies" [strategy] = "strategy">  </strategy-thumbnail> 
</div>

Component 2.ts

import { StrategyService } from './shared/strategy.service'


@Component ({
    selector:'strategy-thumbnail',
    templateUrl:'./strategy-thumbnail.component.html',
    styles: [`
        .pad-left { margin-left: 10px; }
        .well div { color: #bbb; }
        `]
})

export class StrategyThumbnailComponent implements OnInit {
    @Input() strategy:any
    psets:any

    constructor(private strategyService: StrategyService) {

    }

    ngOnInit() {
        this.psets =this.strategyService.getParameterSets(this.strategy.Name)
    }



}

Component 2.html

<div class="well">
    {{strategy?.Name}}
    <param-set *ngFor = "let pset of psets" [pset] = "pset"> </param-set>

</div>

Component 3.ts

import { Component, Input, OnInit } from '@angular/core'
import { StrategyService } from '../strategies/shared/strategy.service'




@Component ({
    selector:'param-set',
    templateUrl:'./param-set.component.html'
})

export class ParamSetComponent {
    @Input() pset: any
    @Input() strategy: any
    returns: any




    constructor(private strategyService: StrategyService) {

    }

    ngOnInit() {

        this.returns = this.strategyService.getReturns(***SomeStrategyName***,this.pset.Name)
    }


}

Component 3.html

<div> {{pset?.Name}} </div>


<return-vector *ngFor = "let return of returns" [return] = "return"> </return-vector>

Component 4.ts

import { Component, Input } from '@angular/core'



@Component ({
    selector:'return-vector',
    templateUrl:'./return-vector.component.html'
})

export class ReturnVectorComponent {
    @Input() strategy:any
    @Input() pset: any
    @Input() return: any
}

Component 4.html

<div>Period: {{return?.period}}, Return: {{return?.return}}</div>

strategy.service.ts

import { Injectable } from '@angular/core'


@Injectable()

export class StrategyService {
    getStrategies() {
        return STRATEGIES
    }

    getStrategy(Name:string) {
        return this.getStrategies().find(strat => strat.Name === Name)
    }

    getParameterSets (Name: string) {
        return this.getStrategy(Name).PSETS
    }

    getParameterSet (StrategyName, PSetName) {
        return this.getParameterSets(StrategyName).find(pset => pset.Name === PSetName)
    }

    getReturns (StrategyName, PSetName) {
        return this.getParameterSet(StrategyName, PSetName).Returns
    }

    getReturn(StrategyName, PSetName, Period) {
        return this.getReturns(StrategyName, PSetName).find(returnperiod => returnperiod.period === Period)
    }

}

const STRATEGIES = [
    { "Name": "SomeStrategyName1", "PSETS: [{"Name":"SomePSetName1", "Returns": [{ "period": "someperiod1", "return" : somenumber1}, {"period": "someperiod2", "return" : somenumber2}]}, {"Name":"SomePSetName2", "Returns": [{ "period": "someperiod3", "return" : somenumber3}, {"period": "someperiod4", "return" : somenumber4}]}]},

{ "Name": "SomeStrategyName2", "PSETS: [{"Name":"SomePSetName3", "Returns": [{ "period": "someperiod5", "return" : somenumber5}, {"period": "someperiod6", "return" : somenumber6}]}, {"Name":"SomePSetName4", "Returns": [{ "period": "someperiod3", "return" : somenumber3}, {"period": "someperiod4", "return" : somenumber4}]}]},

...

{ "Name": "SomeStrategyNameK", "PSETS: [{"Name":"SomePSetName3", "Returns": [{ "period": "someperiod5", "return" : somenumber5}, {"period": "someperiod6", "return" : somenumber6}]}, {"Name":"SomePSetName4", "Returns": [{ "period": "someperiod3", "return" : somenumber3}, {"period": "someperiod4", "return" : somenumber4}]}]}]

Within the provided code, all functionalities are working correctly except one: in Component 3.ts, there is a need to access a specific return set. While the code functions when inputting a specific strategy name (e.g., "SomeStrategyName1"), the goal is for this strategy name to be distinct to the strategies being looped through.

Attempts were made to replace "SomeStrategyName1" with this.strategy.Name since the input parameter was used twice (once in Component 3 and once in Component 2). This approach worked in Component 2, enabling successful access to the Name property of this.strategy when invoking the getParameterSets function in the ts file.

However, Component 3 did not yield the same outcome. An error was encountered: TypeError: Cannot read property 'Name' of undefined at ParamSetComponent.ngOnInit.

Answer №1

Ensure that you pass the required strategy to Component 2 Template for the param-set component:

<div class="well">
  {{strategy?.Name}}
  <param-set 
    *ngFor="let pset of psets" 
    [pset]="pset" 
    [strategy]="strategy">
  </param-set>
</div>

Repeat the same process for Component 3 and beyond...

<div> {{pset?.Name}} </div>
<return-vector 
  *ngFor="let return of returns" 
  [pset]="pset"
  [strategy]="strategy"
  [return]="return">
</return-vector>

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

Opacity effect on input text when it exceeds the input boundaries

I'm having an issue: I need to create inputs with different states, including when the text is longer than the input itself. In this case, the extra text should fade out with a gradient transparency effect: https://i.sstatic.net/r5qQu.jpg Here is my ...

Why is my backend sending two Objects in the http response instead of just one?

When I receive data from my Django backend, sometimes instead of one object I get two objects within the HTTP response. This inconsistency is puzzling because it occurs intermittently - at times there's only one object, while other times there are two ...

Error: A semicolon is required before the statement in an HTML select tag

I am struggling with the code below in my java script: var i = 2; $(".addmore").on('click', function () { count = $('table tr').length; var data = "<tr><td><input type='c ...

Iterate through a local storage object using JavaScript's looping mechanism

I am currently working on a project to create a shopping cart using local storage. I have initialized the local storage with the following code: var cart = {}; cart.products = []; localStorage.setItem('cart', JSON.stringify(cart)); I then use ...

Is it possible to disable a function by clicking on it?

I currently have a website that is utilizing the following plugin: This plugin enables an image to be zoomed in and out through CSS transforms, with default controls for zooming in and out. My goal is to incorporate a reset button that returns the image ...

Combine observables from an id using rxjs in Angular with Firestore

In my Firestore database, I have stored information about people and their pets. Each pet is linked to its owner through an owner ID. // Collection / DocumentID: {data} persons / 'person1': { name: 'Romea' } persons / 'person2&ap ...

Guide on incorporating interactive visuals or features within a panoramic image viewer through the use of THree.js and webGL

Seeking advice on how to incorporate more images and hyperlinks within a panoramic viewer, similar to the examples below: This particular link Panorado js viewer. I have noticed that these viewers feature embedded hyperlinks and overlays, I have attempt ...

Why does TypeScript combine the types of both indices when yielding a tuple?

In my generator function, I am yielding an array containing values of type [number, object]. By using a for...of loop to iterate over the function and destructuring the values with for (const [k, v] of iterator()), I noticed that the type of v is number | ...

Tips on handling communication between different feature modules each handling their own portion of the state

I am currently working on an Angular application that consists of multiple feature modules. My goal is to implement ngrx store in such a way that each module manages its own state. // app.module.ts ... imports: [ ... StoreModule.forRoot(reducers) ...

Guide for accessing Javascript documentation via console?

There are many times when I am coding in Python, that I find myself wanting to quickly access the documentation for a function. In the iPython console, I can easily do this by entering dir?? which retrieves the documentation for the dir function. Is ther ...

Analyzing exif data during the process of uploading a batch of images

My website allows users to upload multiple images simultaneously. I want to check the EXIF rotation tag of each uploaded image in order to manually rotate the images in the browser if needed. I came across a solution for reading the EXIF rotation value of ...

What could be causing the issue with my validation for alphabetical input?

I am currently working on a registration form that only accepts alphabetical input. However, I am facing an issue where my error message appears regardless of whether I input an alphabetical or special character. According to my understanding, the code sho ...

Ways to exchange a return statement within an if statement?

Is it feasible to use if conditions instead of utilizing return when dealing with multiple conditions in our program? var v2=[12,23,44,3,1,3,456,78,22]; function checkresult(v2) { return v2 >= 18; } var a = v2.filter(checkresult); document.get ...

Surfing the web with Internet Explorer means music downloads rather than streaming

My music website functions properly, however I am experiencing issues when accessing it through Internet Explorer. The internet download manager is downloading music from the site without any problems in Chrome and Firefox. Is there a way to prevent or b ...

What is the best way to smoothly scroll to another page using a specific id?

My website consists of multiple pages and I am looking for a code that will allow for smooth scrolling navigation to another page when loading on a specific id or section. For example, in the navbar I have multiple pages with links. When clicking on a lin ...

How can a nullable variable be converted into an interface in TypeScript?

Encountered an issue while working on a vue3.x typescript project. The vue file structure is as follows: <template> <Comp ref="compRef" /> </template> <script lang="ts" setup> import {ref} from "vue& ...

Issue with Electron | JavaScript Runtime

Attempting to utilize WebTorrent with Electron and Node.js for torrent downloading. Here is the code snippet in main.js: const electron = require('electron') const { app, BrowserWindow } = electron const path = require('path') const u ...

Mastering the art of using componentWillUnmount() in ReactJs

According to the official tutorial: componentWillUnmount() is called right before a component is removed and destroyed. It's used for any necessary cleanup tasks like stopping timers, cancelling network requests, or cleaning up DOM elements that we ...

Updating a data with a JavaScript browser script

Recently, I have been attempting to modify the timer in a game using scripts found on various websites. My coding skills are not top-notch, so I am seeking some assistance. I am keeping my fingers crossed that the timer is not server-sided. Upon inspecting ...

Display information from a Google Sheet onto a leaflet map based on specified categories

I am currently facing some challenges while creating a map with markers using data from Google Sheet and leaflet. Despite my efforts, I have encountered a few bugs that are proving to be difficult to resolve: Group Filtering - Although I can successfully ...