updating a property value with retrieved data from an API before sending it to a nested component within an Angular application

Within a parent component, I am receiving data from an API, which is an Object with various properties. The specific property I want to pass to a child component is called "structure". Using Renderer2, I aim to add a class based on the value of this "structure" property.

However, when attempting to add a class to a div element, it returns an error stating that the div is undefined.

Parent Component :

@Component({
  selector: 'dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})

dashboardModel;

loadReport(){
this.ApiService('The-Api-Url',300).subscribe((result)=>{ 
this.dashboardModel = result.dashboardModel;

})
}
///Number 300 is just to show you , it's not important !

Parent Html :

<dashboard-view 
[dashboardModel]="dashboardModel"
></dashboard-view>

Child Component :

@Component({
  selector: 'dashboard-view',
  template: `
<div
  #widgetContainer
  class="container"
  id="widget-view">
</div>
`,
  styleUrls: ['./dashboard-view.component.scss']
})
export class DashboardViewComponent implements OnInit {
constructor(private renderer : Renderer2){}
@Input() dashboardModel
@ViewChild ('widgetContainer') widgetContainer :ElementRef
creatStructure(){
this.renderer.addClass(this.widgetContainer.nativeElement , 'container-edit-mode')
}

ngOninit(){
this.creatStructure()
}
}

Despite calling the creatStructure() method in OnInit, AfterViewInit, and even AfterContentInit, it consistently reports that widgetContainer is Undefined.

stackBlitz Sample Code : https://stackblitz.com/edit/angular-ivy-bdpbwx?file=src/app/child/child.component.ts

Answer №1

If you're having trouble with StackBlitz, consider these alternative solutions:

  1. Avoid using the renderer to set the class. Instead, use a getter in the template to simplify the process and avoid issues with view child objects.

Template:

<div
  #widgetContainer
  class="container"
  [class.container-edit-mode]="isEditMode"
  id="widget-view">
</div>

Component:

public get isEditMode(): boolean {
  return this.dashboardModel
    && this.dashboardModel.structure
    && this.dashboardModel.structure === '12';
}

This approach ensures that the dashboard model is properly set before accessing it (which resolves the issue of API call timing).

  1. Only display the component when data is available. Use *ngIf to conditionally render the component after ensuring that the data has been retrieved.

Parent template:

<ng-container *ngIf="dashboardModel">
  <dashboard-view 
    [dashboardModel]="dashboardModel">
  </dashboard-view>
</ng-container>

Note: Consider addressing any initialisation order complications if sticking to direct renderer usage for setting classes...

  1. Ensure correct initialisation sequence. If manipulating the view with the renderer, do so during or after the ngAfterViewInit stage to prevent undefined view child objects.

You can switch your input to a setter function to manage changes when receiving API data and defer component initialisation until then.

Component:

@Input() public set dashboardModel(value: DashboardModel) {
  this._dashboardModel = value;
  this.initModel();
}

private initModel(): void {
  if (!this.widgetContainer) console.error(`Hopefully this shouldn't happen`);

  if (this._dashboardModel.structure === '12')
    this.renderer.addClass(this.widgetContainer.nativeElement , 'container-edit-mode');
}

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

Issue with Angular 7 Select directive failing to select an option that is loaded asynchronously

Currently, I am facing an issue with a select element in my form. The options of this select are generated through an http request. The problem arises when I use *ngFor to set the options tag based on the received data. Even though the first option appears ...

Is it possible to implement Lazy Loading exclusively on the full path in Angular 2?

Here are the paths that showcase my route configuration: calendar/2016/11/15 = Day View (DayModule) calendar/2016/11 = Month View (MonthModule) calendar/2016 = Year View (YearModule) Each view is equipped with its own Module and Components which I want ...

using Angular's reactive forms to enable/disable form field

I have a straightforward reactive form, utilizing the Angular Material framework. this.firstFormGroup = this.fb.group({ builder_first_name: ['', Validators.required], builder_last_name: ['', Validators.required] ...

Utilizing req.session in an Express application with Angular (written in TypeScript) when deploying the backend and frontend separately on Heroku

I'm currently facing an issue where I am unable to access req.session from my Express app in Angular. Both the backend and frontend are deployed separately on Heroku. I have already configured CORS to handle HTTP requests from Angular to my Express ap ...

What could be causing Angular to not show the outcome? Why is it that only the complete-handler is being triggered?

Just wanted to share my current setup: ASP.NET Core 8 Web API .NET Core 8 backend for frontend Angular SPA served inside a bff using typescript (ES2022) Request flow: -> SPA (Cookie) -> BFF (Token) -> API Struggling with the SPA to display or i ...

What is the process of TypeScript module resolution within the Play framework?

In my Play project, I am interested in incorporating Angular 2 with TypeScript. Utilizing the sbt-typescript plugin and the angular2 WebJAR, I have encountered a situation where Play places the extracted WebJAR in target/web/public/main/lib/angular2. Ideal ...

Tips for creating a "sticky" button in Angular that reveals a menu when clicked

Is there a way to incorporate a feature similar to the "Get help" button on this website: The button, located in the lower right corner, opens a sticky chat menu. I am interested in adding dynamic information to the button (such as the number of tasks a u ...

Struggling with the @typescript-eslint/no-var-requires error when trying to include @axe-core/react? Here's a step-by

I have integrated axe-core/react into my project by: npm install --save-dev @axe-core/react Now, to make it work, I included the following code snippet in my index.tsx file: if (process.env.NODE_ENV !== 'production') { const axe = require(&a ...

What is the best way to implement a late-binding clone method in TypeScript classes?

Creating a simple Cloneable interface for all my data classes in JavaScript is a straightforward task. However, when it comes to typing it properly in TypeScript, things get a bit more complex. Currently, I am putting together a solution like this: class ...

Using Kendo PanelBarItem to incorporate a personalized component as a child element

I was looking to design a component with PanelBarItems in its template. However, I'm facing issues and it doesn't seem to be working. Any suggestions? Main Component: import { Component } from '@angular/core'; @Component({ selecto ...

Creating a method that generates an object containing both a getter and setter functionality, which is determined by a string parameter

I'm struggling to come up with the correct typing for a function that creates an object with setter and getter properties. I believe using template string literals might be the way to go, but I'm having trouble figuring out the right combination ...

Display the column every time the user types something into the search bar

Currently working on an Angular project and I'm trying to figure out how to make the middle column visible whenever the user enters text in the search bar. At the moment, I have a search bar for user input and three flex columns. The middle column is ...

Upcoming 13.4 Error: NEXT_REDIRECT detected in API routes

Here is the code snippet from my /app/api/auth/route.ts file: import { redirect } from 'next/navigation'; export async function GET(req: Request) { try { redirect('/dashboard'); } catch (error) { console.log(error); ...

TypeScript: safely reassigning object properties for type safety

What I aim to achieve I am looking to create a JavaScript function that can remap property names of the first argument using the second argument. The goal is to utilize this remap function to generate query string parameters. For instance, transforming { ...

Ensure that the MUI icon color is set accurately

I created a functional component to set default values for react-admin's BooleanField. Here is the code: import ClearIcon from '@mui/icons-material/Clear' import DoneIcon from '@mui/icons-material/Done' import get from ...

Issue with Angular filtering when utilizing pipe and mapping the response

Code snippet from shop.service.ts getProducts(brandId?: number, typeId?: number) { let params = new HttpParams(); if (brandId){ params = params.append('brandId', brandId.toString()); } if (typeId){ params = params.append('typeId', ...

tslint is flagging an error related to cyclomatic complexity

Within my Angular 8 project, the following dependencies are utilized: "codelyzer": "^5.1.0", "ts-node": "~8.3.0", "tslint": "~5.19.0", Upon executing: ng lint myapp --fix=true An error is raised stating: ERROR: ...html:428:106 - The cyclomatic complex ...

How can I ensure that reactive form fields are properly validated in Angular2?

I am currently facing issues with validating Reactive form field in Angular 2. I have implemented a custom validator for this purpose, but it seems like my approach is not yielding accurate results as some of the test cases are failing. If anyone has insig ...

Issue with displaying selected value and options in Mat-select when using formarray - Reactive forms in Angular

I've been working on the code below to create dropdowns, but I'm having trouble getting the selected value and options to show up in the dropdowns. Can you help me figure out what's wrong with the code? Component code testForm: FormGroup; ...

Issue encountered with TinyMCE integration in Angular 2

As a newcomer to Angular 2, I recently attempted to integrate the TinyMCE editor into my project. I diligently followed the instructions outlined in this guide to create and implement the TinyMCE component: Despite meticulously following each step, I enc ...