Ctfrancia
Ctfrancia

Reputation: 1588

Element from Array removed, Ion DOM element remains on screen, re rendering issue?

Hey guys so the issue that I'm having is that while I add an item to an array the ion-chip is being rendered and added correctly. And whenever I click the chip the value is being removed from the array, which is great! However, the chip remains on the screen.

Alright so the section I am doing is a search component, the search component has a an advanced search option. All options selected from there are sent to a search service that then adds or removes the values to an array, and the search component has a getter function that gets the array from service and adds it to its own array from which the search component's html file does a *ngFor. I have been reading this as well as this. While the latter is the closest I am not actually passing anything to a child. Now... you are probably saying to yourself "HEY!!! that sounds like you are reinventing the wheel and could use ngrx for a state management" in which case you are correct but I'm unable to use it. I have tried observables, IterableDiffers, but can't seem to get it to remove the ion-chip from the screen.

search html:

  <ion-chip color="primary" *ngFor="let item of advancedSearchesSelected; let i = index">
    <ion-icon name="close" color="danger" (click)="removeChipFromSearch(item); advancedSearchesSelected.slice(i, 1)"></ion-icon>
      <ion-label> {{item}} </ion-label>
  </ion-chip>

search.ts

advancedSearchesSelected: Array<string> = [];

constructor( public searchService: SearchService ){}

  ngOnInit () {
    this.advancedSearchesSelected = this.searchService.getSelectedValues();
  }

 removeChipFromSearch(chipToClear: string) {
    this.searchService.updateSearchInfo('remove', chipToClear);
 }

search service.ts

selectedValues: string[] = [];


  public updateSearchInfo = (action: string, item: string) => {
    console.log('UPDATE SEARCH INFO -->', action, item);
    action === 'add' ? 
    this.selectedValues.push(item) : 
    this.clearSingleValue(item);
  };

  private clearSingleValue(item: string) {
    this.selectedValues = this.selectedValues.filter(val => val !== item);
  };

It is adding and removing fine, but the DOM element remains.

Upvotes: 2

Views: 152

Answers (3)

Ctfrancia
Ctfrancia

Reputation: 1588

[SOLVED] Thanks for your help @SeverinKlug, however, that was not the solution that solved the issue. while that does change the reference the problem was that the reference is being changed elsewhere not the same file and the search component was not being notified of the change from the search service and needed to be remedied by using a Behavior Subject and found the solution here

this is how I changed my code:

search.html:

  <ion-chip color="primary" *ngFor="let item of advancedSearchesSelected">
    <ion-icon name="close" color="danger" (click)="removeChipFromSearch(item)"></ion-icon>
      <ion-label> {{item}} </ion-label>
  </ion-chip>

search.ts

  ngOnInit () {
    this.searchService
    .getSelectedValues()
    .subscribe(item => {
      this.advancedSearchesSelected = item;
    });
  }

search.service.ts

export class SearchService {
  constructor() {}
  private selectedValues: string[] = new Array<string>();
  private selectedValues$: BehaviorSubject<string[]> = new BehaviorSubject<string[]>(this.selectedValues);


  public getSelectedValues() {
    return this.selectedValues$;
  };

  public updateSearchInfo = (action: string, item: string) => {
    if (action === 'add') {
      this.selectedValues.push(item);
      this.selectedValues$.next(this.selectedValues);
    } else this.clearSingleValue(item);
  };

  private clearSingleValue(item: string) {
    this.selectedValues = this.selectedValues.filter(val => val !== item);
    this.selectedValues$.next(this.selectedValues);
  };

Upvotes: 2

dev-dan
dev-dan

Reputation: 6283

you need to get the Change Detection involved so the view will know that there has been an update to the data. As mentioned there are ways to do this. I would opt for manually running detectChanges();

Be sure to import.

import { ChangeDetectorRef } from '@angular/core';

controller

constructor(private ref: ChangeDetectorRef) {}

public removeChipFromSearch(chipToClear: string): void 
{
    this.searchService.updateSearchInfo('remove', chipToClear);
    this.ref.detectChanges(); // for change detection.
}

Upvotes: 2

Severin Klug
Severin Klug

Reputation: 754

You didn't change the ArrayObjects reference. Change Detection and therefore DOM update is only triggered if references change. You can reassign your arrays reference a copy of itself.

https://stackoverflow.com/a/20547803/7329611

arr2 = [...arr1];

Upvotes: 0

Related Questions