DoktoriPartise19
DoktoriPartise19

Reputation: 15

HTML Dropdown disappears after a value is set to null in Angular

I have two values power and mainPower which describe the same thing but mainPower saves an id of type Long in the backend and power saves all attributes of this dto. With the code below I can update a hero's power, meaning I can change it from something to the other and also make it null (meaning no power).

The problem is that when a power is set to null or it was null before, the dropdown menu disappears. I don't want the dropdown to disappear, I just want it to say "no power" when it is null and I should be able to change it from null to something.

hero-detail.component.html

<form #heroUpdateForm = "ngForm">
      {{diagnostic}}
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name"
               required
               *ngIf="hero" [(ngModel)]="hero.name" name="name">
      </div>

      <div class="form-group">
        <label for="desc">Description</label>
        <input type="text"  class="form-control" id="desc"
              *ngIf="hero" [(ngModel)]="hero.desc" name="desc">
      </div>

      <div class="form-group" *ngIf="hero?.power">
        <label for="power">Main Power</label>
        <select class="form-control"  id="power"
                required
                [(ngModel)]="hero.mainPower" name="power">
          <option [ngValue]="null">no power</option>
          <ng-container *ngFor="let power of powers">
            <option [value]="power.id">{{power.name}}</option>
          </ng-container>
        </select>
      </div>
    </form>

hero-detail.component.ts

export class HeroDetailComponent implements OnInit {
  public heroes: Hero[];
  public powers: Power[];
  submitted = false;
  private hero: Hero;

  constructor(
    private route: ActivatedRoute,
    private heroService: HeroService,
    private powerService: PowerService,
    private location: Location,
    private router: Router
  ) {}

  ngOnInit(): void {
    this.getHero();
    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
    this.getHeroes();
    this.getPowers();
  }

  getHero(): void{
    const id = +this.route.snapshot.paramMap.get('id');
    this.heroService.getHero(id).subscribe(
      (hero: Hero) => {
        this.hero = hero;
        if (hero.power != null) {
          this.powerService.getPowerById(hero.power).subscribe(
            (powerResponse) => {
              hero.power = powerResponse;
            }
          );
        }
      });
  }
  public getHeroes(): void {
    this.heroService.getHeroes().subscribe(
      (response: Hero[]) => {
        this.hero = response;
        },
      (error: HttpErrorResponse) => {
        alert(error.message);
      }
    );
  }

  public getPowers(): void {
    this.powerService.getAllPowers().subscribe(
      (response: Power[]) => {
        this.power = response;
      },
      (error: HttpErrorResponse) => {
        alert(error.message);
      }
    );
  }

  goBack(): void {
    this.location.back();
  }

  save(): void {
    this.heroService.updateHero(this.hero, this.hero.id)
      .subscribe(() => this.goBack());
  }
  onSubmit() {this.submitted = true;}

  get diagnostic() {return JSON.stringify(this.hero);}

Upvotes: 0

Views: 568

Answers (1)

Bargros
Bargros

Reputation: 531

Is obvious why it'll disappear, look at your template again:

       <div class="form-group" *ngIf="hero?.power"> <!-- lookie here, if either hero or power is null this element along with everything in it will be gone!! -->
         <label for="power">Main Power</label>
         <select class="form-control"  id="power"    <!-- your select is inside the div above with the ng if -->
                required
                [(ngModel)]="hero.mainPower" name="power">
         <option [ngValue]="null">no power</option>
         <ng-container *ngFor="let power of powers">
           <option [value]="power.id">{{power.name}}</option>
         </ng-container>
       </select>

essentially the ngIf you have in the div surrounding the select element says the following:

  • if(ngIf) hero and power -> display element
  • if(ngIf) no hero and power -> remove element

You might not want to have *ngIf="hero?.power" perhaps you should just check if there is a hero *ngIf="hero" instead

Upvotes: 2

Related Questions