0

I have created an angular 8 app that allows a user to choose a date from a angular material date picker control. The app then sends a request a Mongodb using NodeJS to return a list of available daily sessions. This part of my app is working fine. The returned daily sessions are dynamically displayed as buttons in the html. My code iterates through the list of available sessions and creates a button in the html using a angular *ngFor loop. My problem is that when the user then wants to choose another date from the date picker the new list of sessions is returned and the new list of available dates creates more buttons in the html using the *ngFor loop i.e. the new list of buttons is appended to the existing list of buttons. What I actually want is the previously displayed button in the HTML to be deleted from the DOM and the new list of buttons for the newly selected date to be displayed in their place. Does anybody know how to do this? Thanks!

Below is my component ts file:-

import { Component, OnInit, ViewChild, ElementRef, Renderer2 } from '@angular/core';
import { Tank } from '../../models/tank.model';

import { FormGroup, FormControl } from '@angular/forms';
import * as moment from 'moment';
import { TankService } from 'src/app/services/tank.service';

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

export class BookingComponent implements OnInit {

  selectedDate: any;
  convertedDate: string;
  tankAvailability: Tank[];
  dateSelectionButtonPressed = false;
  tankOneAvailability: string[] = [];

  bookingForm: FormGroup;

  constructor(private tankService: TankService) { }

  ngOnInit(): void {
    this.bookingForm = new FormGroup({
       enteredDate: new FormControl(),
    });
  }

  onSelect(event) {
    this.selectedDate = event;

    this.convertedDate = moment(event).format('DD-MM-YYYY');
    this.bookingForm.patchValue({
      enteredDate: this.convertedDate
    });
  }

  getTankAvailabilityByDate() {
    this.dateSelectionButtonPressed = false;
    this.tankAvailability = [];
    if (this.convertedDate) {
      this.tankService.getTankAvailabilityByDate(this.convertedDate)
        .subscribe(tanks => {
          this.tankAvailability = tanks.tanks;
          this.populateAvailableSessions();
        });
    }
  }

  populateAvailableSessions() {
    this.dateSelectionButtonPressed = true;
    for(let i = 0; i < this.tankAvailability.length; i++) {
      if (this.tankAvailability[i].tankNumber === 1) {
          console.log(this.tankAvailability[i]);
          if (this.tankAvailability[i].sessionOne === false) {
            this.tankOneAvailability.push('07:00');
          }
          if (this.tankAvailability[i].sessionTwo === false) {
            this.tankOneAvailability.push('09:00');
          }
          if (this.tankAvailability[i].sessionThree === false) {
            this.tankOneAvailability.push('11:00');
          }
          if (this.tankAvailability[i].sessionFour === false) {
            this.tankOneAvailability.push('13:00');
          }
          if (this.tankAvailability[i].sessionFive === false) {
            this.tankOneAvailability.push('15:00');
          }
          console.log(this.tankOneAvailability);
        }
      }
  }
}

Below is my component HTML file:-

<mat-card>
  <div class="center-section">
    <h1>Book a float</h1>

    <p>
      Select a date on the calendar below and we will display all the available float times
    </p>

    <form (submit)="getTankAvailabilityByDate()" [formGroup]="bookingForm">
      <div class="calendar-wrapper">
        <mat-calendar [selected]="selectedDate" (selectedChange)="onSelect($event)"></mat-calendar>
      </div>
      <mat-form-field class="invisible-field">
        <input matInput formControlName="enteredDate">
      </mat-form-field>
      <button mat-raised-button color="primary" type="submit">Get availability</button>
    </form>
  </div>
</mat-card>

<mat-card *ngIf="dateSelectionButtonPressed">
    <mat-card-header>
        <mat-card-title>Tank 1</mat-card-title>
    </mat-card-header>
    <mat-card-content *ngFor="let session of tankOneAvailability">
       <button mat-raised-button color="primary">{{session}}</button>
    </mat-card-content>
</mat-card>

2 Answers 2

3

You would need to empty the array to show new list of buttons. Below code needs to be changed

populateAvailableSessions() {
    this.dateSelectionButtonPressed = true;
    // always create new array so new values are pushed
    this.tankOneAvailability = []; 
    for(let i = 0; i < this.tankAvailability.length; i++) {
      if (this.tankAvailability[i].tankNumber === 1) {
          console.log(this.tankAvailability[i]);
          if (this.tankAvailability[i].sessionOne === false) {
            this.tankOneAvailability.push('07:00');
          }
          if (this.tankAvailability[i].sessionTwo === false) {
            this.tankOneAvailability.push('09:00');
          }
          if (this.tankAvailability[i].sessionThree === false) {
            this.tankOneAvailability.push('11:00');
          }
          if (this.tankAvailability[i].sessionFour === false) {
            this.tankOneAvailability.push('13:00');
          }
          if (this.tankAvailability[i].sessionFive === false) {
            this.tankOneAvailability.push('15:00');
          }
          console.log(this.tankOneAvailability);
        }
      }
  }

Hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Ah yes, of course, I was only clearing one of the arrays. Thank you for your help. Well spotted :-)
1

You need to reinitialise the tankOneAvailability array each time you run a new query like you do for the tankAvailability (currently you keep pushing more values into it)

i.e.

 getTankAvailabilityByDate() {
    this.dateSelectionButtonPressed = false;
    this.tankAvailability = [];
    this.tankOneAvailability = []

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.