What is the best way to dynamically load two child components in Angular 8 based on certain conditions?

Imagine the following structure:

<app-component>
    <university-component></university-component>
    <highSchool-component></highSchool-component>
</app-component>

Now, there is a dialog component (dialog-component) within app-component that presents 2 options: university and high school:

<form nz-form [nzLayout]="'inline'" [formGroup]="validateForm" (ngSubmit)="submitForm()">
      <h3> Please select your academic level </h3>
            <nz-form-control [nzErrorTip]="getErrorTip('studentLevel')">
              <nz-radio-group [(ngModel)]="radioValue" formControlName="studentLevel" nzButtonStyle="solid" nzSize="small">

                  <input type="radio" name="radio3" id="university" (change)="setRouter(2)">
                      <label class="universite-label four col" nzValue="universite" for="universite">University</label>
                  <input type="radio" name="radio3" id="highSchool" (change)="setRouter(1)">
                      <label class="lycee-label four col" nzValue="lycee" for="lycee" >High School</label>

              </nz-radio-group>
            </nz-form-control>>
            
       <div>
       <label nzType="flex" nzJustify="center" nzAlign="middle" nz-radio-button (click)="changeRoute()" mat-dialog-close >GO</label>
       </div>

</form>

If I select University, how can I make app-component load university-component, and if I choose High School, how can I make app-component load highSchool-component?

Answer №1

It seems like radioValue is already linked to ngModel, allowing you to implement the following code snippet. This assumes that AppComponent has the necessary access to radioValue.

<app-component>
  <university-component *ngIf="radioValue === 'universityComponentVal'"> </university-compnent>
  <high-school-component *ngIf="radioValue === 'highSchoolVal'"></high-school-component>
</app-component>

If more conditionally rendered components need to be managed, consider utilizing ngSwitch and ngSwtichCase. https://angular.io/api/common/NgSwitchCase

Answer №2

In my opinion, opting for routes instead of ngIf would be a better approach in this scenario, especially if there are shared variables with the parent component. Using routes not only provides a cleaner solution but also enables deep linking for improved user experience by eliminating the need to select a value repeatedly.

export const appRoutes: Routes = [
  ... Include any other existing routes
  {
    path: 'university',
    component: UniversityComponent,
  },
  {
    path: 'highSchool',
    component: HighSchoolComponent
  }
};

@NgModule({
  imports: [
    ...
    RouterModule.forRoot(appRoutes)
  ]
})
export class AppModule {}

You can navigate to these routes either from the HTML using Angular's routerLink directive or from the function triggered by the form.

@Component({
  ...
})
export class AppComponent {
  radioValue: 'university' | 'highSchool';
 
  constructor(private router: Router) {}

  changeRoute() {
    this.router.navigate([this.radioValue]);
  }
}

It appears that you are combining formControlName with ngModel, which may lead to errors. The suggested method utilizes the value from ngModel; similarly, you can access the form value in the same manner.

Answer №3

I want to express my gratitude for all the helpful responses,

After much trial and error, I finally discovered the solution. I decided to create a new service called "level.service.ts" :

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LevelService {

  isCollegeStudent: boolean = true;

  constructor() { }

  highSchool() {
    this.isCollegeStudent = false;
  }

  university() {
    this.isCollegeStudent = true;
  } 
} 

Then, in the main app-component file:

<app-component>
    <university-component *ngIf="levelService.isCollegeStudent"></university-component>
    <highSchool-component *ngIf="!levelService.isCollegeStudent"></highSchool-component>
</app-component>

In addition, I made modifications to dialog.component.html involving two (click) methods:

<form nz-form [nzLayout]="'inline'" [formGroup]="validateForm" (ngSubmit)="submitForm()">
      <h3> Kindly indicate your current academic level </h3>
            <nz-form-control [nzErrorTip]="getErrorTip('studentLevel')">
              <nz-radio-group [(ngModel)]="radioValue" formControlName="studentLevel" nzButtonStyle="solid" nzSize="small">

                  <input type="radio" name="radio3" id="university" (change)="setRouter(2)">
                      <label class="universite-label four col" nzValue="universite" for="universite" (click)="university()">University</label>
                  <input type="radio" name="radio3" id="college" (change)="setRouter(1)">
                      <label class="college-label four col" nzValue="college" for="college" (click)="highSchool()">College/Campus</label>

              </nz-radio-group>
            </nz-form-control>
            
       <div>
       <label nzType="flex" nzJustify="center" nzAlign="middle" nz-radio-button (click)="changeRoute()" mat-dialog-close >GO</label>
       </div>

</form>

Lastly, I refined the functionality of dialog.component.ts as follows:

import { Component} from '@angular/core';
import { UniversityService } from 'src/app/services/university.service';
// other imports

@Component({
  selector: 'app-dialog-video',
  templateUrl: './dialog-video.component.html',
  styleUrls: ['./dialog-video.component.css']
})

export class DialogVideoComponent implements OnInit {

  @Input() radioValue = 'school'

  isCollegeStudent: string = 'college';

  // constructor() { } 
 
 // additional operations

  ngOnInit() {
    // this.universityService.isCollegeStudent = this.radioValue;
    this.universityService.collegeCampus(),
    this.universityService.universite()
  }

  highSchool() {
    this.universityService.collegeCampus();
  }

  university() {
    this.universityService.universite();
  }

}

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

What is the best way to reset a setInterval ID in Angular?

In my Angular project, I am developing a simple timer functionality that consists of two buttons – one button to start the timer and another to stop it. The timer uses setInterval with a delay of 1000ms. However, when the stop button is pressed, the time ...

Caution: Ensuring that every child item in a list possesses a distinct "key" prop is crucial when working with React in TypeScript

Encountering this issue in React (TypeScript): Notification: Each child in a list requires a unique "key" prop. Review the render method of MyCollection Below is the implementation of MyCollection: export default function MyCollection(props:any ) { le ...

Exploring the Comma Operator in Typescript

According to information from MDN: The comma operator examines each of its components (working leftward) and gives back the outcome of the last one. To experiment with this, I converted this arrow function: const pushToArray = (a: FormArray, f: FormGr ...

Angular synchronous observables are designed to provide real-time data

API integration is a crucial part of my process for obtaining information. However, the data retrieval can be inconsistent at times; I may receive all the necessary information, only portions of it, or the data might not be in the correct order. getData(s ...

How to prevent or disable the hardware back button on an Ionic 4 device

I am currently utilizing Angular routing with @angular/router in my Ionic 4 project. I have been attempting to disable the device back-button in Ionic 4, but prevent-default is not working for me. Below is the code snippet from my app.component.ts file: ...

Obtaining a TemplateRef from a directive: The process explained

I am currently working on developing a structural directive that can insert a TemplateRef, although the actual TemplateRef is defined in a separate location. Situation There are times when I need to add custom content within an existing element, but due ...

Combining Promises in Typescript to create a single Promise

Is there a way for me to return the temp_data object filled with data after using .map? Currently, it always returns undefined because I initialize temp_data as an empty object. But if I don't do this, I can't use LooseObject. Can anyone suggest ...

What is the reason behind line-height not affecting the clickable area when reduced?

I have been working on a personal project where I added thumbnails for images that can be scrolled through and clicked to set the main image. However, I encountered a strange issue. To demonstrate the problem, I created a Stackblitz project here: https:// ...

What causes the website to malfunction when I refresh the page?

I utilized a Fuse template to construct my angular project. However, upon reloading the page, I encountered broken website elements. The error message displayed is as follows: Server Error 404 - File or directory not found. The resource you are looking fo ...

Encountering an issue with subscribing wait times

Whenever a button is clicked within my application, I have a requirement to upload specific items to the API before proceeding with the next functionality. I've experimented with various approaches to ensure that the code waits for execution, but it ...

Ag-grid allows for the creation of multiple individual detail grids that are connected to a single

I noticed in the ag-grid documentation that all the master/detail examples feature only a single detail grid implementation. Is it possible to incorporate multiple (different) detail grids within one master grid, specifically in one row? ...

Error: Missing provider for String value

Encountering an error in the browser after adding a string parameter to the constructor of my class: https://i.sstatic.net/Hh1wM.png The structure of my class is as follows: import { Component, OnInit } from '@angular/core'; import { MatrixCo ...

What sets apart npm correlation-id from uuid?

Can you please explain the distinction between the uuid and correlation-id npm packages? It seems that correlation-id actually utilizes the uuid package internally.. When would you recommend using correlation-id over uuid? Important: I am not utilizing ...

Showing a ng2-pdf-viewer PDF contained within a stream

My webpage integrates the ng2-pdf-viewer library: <pdf-viewer [src]="fileToDownload" [render-text]="true" style="display: block;"></pdf-viewer> A Node API is used to fetch the PDF file and return a URL: this.httpC ...

Why is it important to understand the role of ngOnInit() in Angular?

Is it possible to execute all the identical functions it does in the constructor? ...

Displaying the default value in a Material-UI v5 select component

I am looking to display the default value in case nothing has been selected yet for the mui v5 select component below, but currently it appears empty... <StyledCustomDataSelect variant='outlined' labelId='demo-simple- ...

What is the significance of mapping transformations on objects within MongoDB?

I encountered an issue. Every time I try to create a map in MongoDB, for example a shop, guildID: id, ownerID: owner_id, _premium: 0, Moderation:{ auto:false, prefix:'k!', muter ...

Utilizing Angular 2 or TypeScript to Retrieve Visitor's Location

I initially began using ServerVariables["HTTP_CF_IPCOUNTRY"] on the backend server, but it's proving to be too slow. I'm looking for an Angular or TypeScript alternative to speed things up. ...

Looking to retrieve the selected item from the list using console.log

Brief explanation: I am trying to retrieve the clicked item from a list using console.log(i.match). Please refer to my **home.html** code snippet below for how the list is dynamically generated. home.html <ion-card> <ion-card-content *ngFor="l ...

Issues arise when attempting to use the Android KeyUp, KeyDown, and KeyPress events in conjunction with Angular2

I am encountering an issue where I consistently receive a keyCode of 229 in Android Chrome browsers when running either: <input type="text" (keydown)="testKeyCodes($event)"/> <!-- or --> <input type="text" (keyup)="testKeyCodes($event)"/& ...