简体   繁体   中英

Angular 11 - Modal Method checks for value in array and returns false even when the constructor loads the array

I have a form that registers a new Group of courses called 'areas'. The form have a button that calls a modal window and allows the user to select the desired courses and add them to the form list.

The initial function seems to work fine. When I select a course in the dialog, the course is added to the Parent Component array. Then I check if the course is already selected in order to show a button to deselect the course.

The problem lies when I close the Modal Dialog and open it again. The "isCourseSelected" method (which checks if the "course" object is inside the array) doesn't work. It returns false even if the constructor populates the array "modalSelectedCourses" from the initialState of the modalService.

Here is the code which have the problem:

import { ChangeDetectorRef, Component, EventEmitter, OnInit, Output } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { FormControl, FormGroup } from '@angular/forms';
import { FileUploadValidators } from '@iplab/ngx-file-upload';
import { BsModalService, BsModalRef } from 'ngx-bootstrap/modal';
import { isThisTypeNode } from 'typescript';
import { Course } from '../../../../shared/models/course.model';

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

export class AreaFormComponent implements OnInit {
  public selectedCourses: Course[];
  bsModalRef?: BsModalRef;
  public animation: boolean = false;
  public multiple: boolean = false;
  private filesControl = new FormControl(null, FileUploadValidators.filesLimit(2));

  public demoForm = new FormGroup({
    files: this.filesControl
  });

  constructor(public modalService: BsModalService, private cd: ChangeDetectorRef) {
  }

  get staticSelectedAreas() {
    return this.selectedCourses;
  }

  public processSelection(course: Course) {
    if (this.selectedCourses.indexOf(course) !== -1) {
      this.selectedCourses = this.selectedCourses.filter((curCourse) => course.id !== curCourse.id);
    } else {
      this.selectedCourses.push(course);
    }
    this.cd.markForCheck();
  }

  public toggleStatus(): void {
      this.filesControl.disabled ? this.filesControl.enable() : this.filesControl.disable();
  }

  public toggleMultiple() {
      this.multiple = !this.multiple;
  }

  public clear(): void {
      this.filesControl.setValue([]);
  }

  ngOnInit(): void {
    this.selectedCourses = [];
  }

  openModalWithComponent() {
    const initialState = {
      modalSelectedCourses: this.selectedCourses
  };
    this.bsModalRef = this.modalService.show(CoursesModalComponent, {initialState, class: 'modal-lg'});
    this.bsModalRef.content.notifyParent.subscribe((e) => {
      this.processSelection(e);
    });
    this.bsModalRef.content.closeBtnName = 'Close';
  }

}

@Component({
  selector: 'app-search-courses-list',
  templateUrl: './courses-list-modal.component.html',
  styleUrls: ['./area-form.component.scss'],
})

export class CoursesModalComponent implements OnInit {
  @Output() notifyParent = new EventEmitter<Course>();
  title?: string = 'Buscar Cursos';
  closeBtnName?: string;
  courses: Course[] = [];
  modalSelectedCourses: Course[] = [];

  constructor(public bsModalRef: BsModalRef, firestore: AngularFirestore, public modalService: BsModalService) {
    firestore.collection('courses').valueChanges({idField: 'id'}).forEach((course) => {
      course.forEach((tempCourse) => {
        const newCourse: Course = new Course().deserialize(tempCourse);
        this.courses.push(newCourse);
      });
    });
    this.modalSelectedCourses = this.modalService.config.initialState['modalSelectedCourses'];
    console.log(this.modalSelectedCourses);
  }

  public addSelectedCourse(course: Course) {
    this.notifyParent.emit(course);
    this.modalSelectedCourses.push(course);
  }

  public removeSelectedCourse(course: Course) {
    this.notifyParent.emit(course);
    this.modalSelectedCourses = this.modalSelectedCourses.filter((curCourse) => course.id !== curCourse.id);
  }

  public isCourseSelected(course: Course) {
    if (this.modalSelectedCourses.indexOf(course) !== -1) {
      return true;
    } else {
      return false;
    }
  }

  ngOnInit() {
  }
}

Also, here is the code of the modal template "courses-list-modal.component":

<div class="modal-header">
    <h4 class="modal-title pull-left">{{title}}</h4>
    <button type="button" class="btn-close close pull-right" aria-label="Close" (click)="bsModalRef.hide()">
      <span aria-hidden="true" class="visually-hidden">&times;</span>
    </button>
</div>
<div class="modal-body">
    <div class="row">
        <div class="col-sm-8">
            <div class="search-course-div">
                <input type="text" class="form-control search-course-textfield" name="search" placeholder="Buscar curso"><i class="fa fa-search"></i>
            </div>
        </div>
        <div class="col-sm-4">
            <button class="btn btn-primary">+ Crear curso</button>
        </div>
    </div>
    <div class="courses-table">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Nombre del curso</th>
                    <th>Cant. de lecciones</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                <ng-container *ngIf="courses; else noCourses">
                    <tr *ngFor="let course of courses">
                        <td>{{ course.name }}</td>
                        <td>##</td>
                        <td>
                            <ng-container *ngIf="isCourseSelected(course); else notSelectedTemplate">
                                <button (click)="removeSelectedCourse(course)" type="button" class="btn btn-primary">Asignado <i class="fa fa-check-circle"></i></button>
                            </ng-container>
                            <ng-template #notSelectedTemplate>
                                <button (click)="addSelectedCourse(course);" type="button" class="btn btn-outline-primary">Asignar</button>
                            </ng-template>

                        </td>
                    </tr>
                </ng-container>
                <ng-template #noCourses>
                    <tr>
                        <td colspan="3">No hay cursos disponibles</td>
                    </tr>
                </ng-template>

            </tbody>
        </table>
    </div>
</div>

I don't know why the method returns false on the second time I open the dialog.

Thank you in advance for your support!

The workaround I though was to make the "selectedCourses" a static variable. It wasn't working because the this.modalSelectedCourses inside "isCourseSelected" method was always empty on init. So, making the variable static, it will mantain the data on memory and checked the real array values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM