user12050907
user12050907

Reputation:

What is the best approach to hide/show component depending on some condition in Angular 8

Guys thank you for your help. After getting lots of suggestions and mixed and matched all those suggested code I am able to solve the earlier issue. However I am getting the below error after using @ViewChild decorators in console.

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'count1'. Current value: 'count2'.

My Parent ts file code is following

import { Component, OnInit, Input, ViewEncapsulation, ViewChild, AfterViewInit} from '@angular/core';
import { NagivationComponent } from '../nagivation/nagivation.component';
import { CensusComponent } from '../your-data/census/census.component';
import { ApplicationComponent } from '../your-data/application/application.component';

@Component({
  selector: 'app-your-data',
  templateUrl: './your-data.component.html',
  styleUrls: ['./your-data.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class YourDataComponent implements AfterViewInit{
  @Input() step;

  count:string = 'count1';
  constructor() {

  }
  @ViewChild(CensusComponent, {static: false}) census: CensusComponent;
  ngAfterViewInit() {
    this.count = this.census.getSection(); 
  }      
}

And the your-data.component.html code is following

<div [ngSwitch]="count">
   <app-census *ngSwitchCase="'count1'"></app-census>
   <app-application *ngSwitchCase="'count2'"></app-application>
</div>

Upvotes: 0

Views: 1084

Answers (6)

Sushrut Singh Sisodiya
Sushrut Singh Sisodiya

Reputation: 990

Just use ngIf and in condition use count which will be incremented on click of next button

<div class='container'>
  <div class='row'>
    <div class='setup-content'>
      <h1>Confirm Data/Answer Questions</h1>
      <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
      <app-census *ngIf="count === 1"></app-census>
      <app-census1 *ngIf="count === 2"></app-census1>
    </div>
  </div>
</div>

Upvotes: 1

user12050907
user12050907

Reputation:

The above issue has been resolved to change mode from dev to prod. in main.ts

enableProdMode();

Please remove the if condition. Below is my whole solve code

Parent Component .html file

<div [ngSwitch]=count>
      <app-census *ngSwitchCase="'count1'"></app-census>
      <app-application *ngSwitchCase="'count2'"></app-application>
   </div>

Parent Component file

import { Component, OnInit, Input, ViewEncapsulation, ViewChild, AfterViewInit} from '@angular/core';
import { NagivationComponent } from '../nagivation/nagivation.component';
import { CensusComponent } from '../your-data/census/census.component';
import { ApplicationComponent } from '../your-data/application/application.component';

@Component({
  selector: 'app-your-data',
  templateUrl: './your-data.component.html',
  styleUrls: ['./your-data.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class YourDataComponent implements AfterViewInit{
  @Input() step;

  count:string = 'count1';
  constructor() {

  }
  @ViewChild(CensusComponent, {static: false}) census: CensusComponent;
  ngAfterViewInit() {
    this.count = this.census.getSection(); 
  }

}

Child component html

<button class="sub btn btn-primary btn-lg nbtn" type="button" (click)="getSection()"><span>NEXT</span></button>

Child component file

import { Component, OnInit, Input } from '@angular/core';
import { YourDataComponent } from '../your-data.component';
@Component({
  selector: 'app-census',
  templateUrl: './census.component.html',
  styleUrls: ['./census.component.css']
})
export class CensusComponent implements OnInit {
  @Input() count:string;
  getSection(){
    this.count = 'count2';
    return this.count;
  }
  constructor() {

  }

  ngOnInit(): void {
  }

}

Upvotes: 0

sunil
sunil

Reputation: 195

you can use *ngTemplateOutlet to display component based on count variable.

 <div class='container'>
          <div class='row'>
            <div class='setup-content'>
              <h1>Confirm Data/Answer Questions</h1>
              <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
           <div *ngif="count == 1"> 
 <app-census></app-census>
<ng-container *ngTemplateOutlet="template"></ng-container>
           </div>
         <div *ngif="count == 2"> 
 <app-census1></app-census1>
<ng-container *ngTemplateOutlet="template"></ng-container>
           </div>
            </div>
          </div>
        </div>

    <ng-template #template>
      <router-outlet>
      </router-outlet>
    </ng-template>

Upvotes: 0

Supamiu
Supamiu

Reputation: 8731

You can use *ngSwitch and *ngSwitchCase for a cleaner approach when you have more than two steps:

<div class='container'>
  <div class='row'>
    <div class='setup-content'>
      <h1>Confirm Data/Answer Questions</h1>
      <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
      <ng-container [ngSwitch]="count">
          <app-census *ngSwitchCase="1"></app-census>
          <app-census1 *ngSwitchCase="2"></app-census1>
      </ng-container>
    </div>
  </div>
</div>

Upvotes: 0

Barremian
Barremian

Reputation: 31105

You could either use *ngIf or *ngSwitchCase directive to show components based on a condition.

Template:

<div [ngSwitch]="step">
  <div *ngSwitchCase="'step1'"><app-census1></app-census1></div>
  <div *ngSwitchCase="'step2'"><app-census2></app-census2></div>
  <div *ngSwitchCase="'step3'"><app-census3></app-census3></div>
  <div *ngSwitchCase="'step4'"><app-census4></app-census4></div>
  <div *ngSwitchDefault>Default</div>
</div>

Component

import { Component, OnInit, Input, ViewEncapsulation } from '@angular/core';
import { NagivationComponent } from '../nagivation/nagivation.component';

@Component({
  selector: 'app-your-data',
  templateUrl: './your-data.component.html',
  styleUrls: ['./your-data.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class YourDataComponent implements OnInit {
  @Input() step;
  count:number;
  step: string;

  constructor() { }

  ngOnInit() {
    // here set this.step = 'step1' | 'step2' | 'step3' | 'step4'      
  }
}

For stepper based applications, you could refer here for a sample application. Enabling the linear mode in that application will make sure you need to enter some data before you can proceed to the next step.

Upvotes: 0

Mustahsan
Mustahsan

Reputation: 3862

Use *ngIf to show components based on steps, try:

<div class='container'>
  <div class='row'>
    <div class='setup-content'>
      <h1>Confirm Data/Answer Questions</h1>
      <p>Please answer all questions below. If you have questions about the data provided on this screen, please contact << Broker >> at << Phone >> or << Email >>.</p>
      <app-census *ngIf="step == 1"></app-census>
      <app-census1 *ngIf="step == 2"></app-census1>
    </div>
  </div>
</div>

Upvotes: 0

Related Questions