Home > Software design >  Dynamic array with angular
Dynamic array with angular

Time:12-13

Basically I have an api that returns data when I do a search, I push them into an array and I display them by doing an ngFor in my html.

When I want to do a new search it's the same function that is called, but the html is not updated while I get new data.

It always appears the old data recovered the first time.

To search, i used this code :

SearchBar.component.ts

export class RechercheToutComponent implements OnInit {

  searchInput = new FormControl('');

  constructor(
    private router: Router,
    private recherche: RechercheComponent
  ) { }

  ngOnInit(): void {
  }

  search() {
    if(this.router.url.match(/recherche.*!/)){
      this.recherche.searchResult(this.searchInput.value)
    }else{
      this.router.navigate(['/recherche'], {queryParams: {search: this.searchInput.value}}).then(r => this.recherche.searchResult(this.searchInput.value))
    }
  }
}

SearBar.component.html

<form  (ngSubmit)="search()">
  <div >
    <input type="text"
           [formControl]="searchInput"
           placeholder="Rechercher dans Intra"
    />
    <button type="submit" >
      <mat-icon>search</mat-icon>
    </button>
  </div>
</form>

Search.component.ts

export class RechercheComponent implements OnInit {

  searchParam: any;

  results$: Observable<Array<any>>;

  isResultLoading: boolean = true;

  constructor(
    private route: ActivatedRoute,
    private http: HttpClient
  ) {
  }

  ngOnInit(): void {
    this.route.queryParams.subscribe(params => {
      this.searchParam = params['search']
    });
    this.searchResult(this.searchParam);
  }

  searchResult(searchParam) {
    this.http.get(`${environment.apiUrl}/Recherchetout.php`, {params: {search: searchParam}}).subscribe(
      (data: Array<any>) => {
        this.results$ = of(data)
        this.isResultLoading = false;
      }
    );
  }
}

Search.component.html

<div >
  <div  *ngIf="isResultLoading">
    <app-spinner></app-spinner>
  </div>
  <div  *ngIf="!isResultLoading">
    <div *ngFor="let oui of results$ | async">
      <div *ngIf="oui.produit != undefined">
        {{ oui.produit.pdf }}
      </div>
    </div>
  </div>  
</div>

I tried to create observables but it didn't work, with a simple array too.

So my question is: Why is my data not updating on my html? And how to do it ?

Sorry in advance for the mistakes, or for the disastrous code I begin in angular

CodePudding user response:

Assuming you want to refresh the search every time a URL change, update you ngOnInit by moving this.searchResult(this.searchParam); inside the subscribe method

ngOnInit(): void {
    this.route.queryParams.subscribe(params => {
      this.searchParam = params['search']
      this.searchResult(this.searchParam);
    });
  }

with this searchResult will be called every time the router parameters get change instead of updating for the first time ngOnInit get called

CodePudding user response:

you are injecting RechercheComponent inside the SearchBar component, angular will create different instance than the one used on the UI.

to send data between multiple components create a parent component and use it to allow communication between the two components (use the Input and Output attributes).

make your system navigate to the parent then

Parent.Component.ts

export class ParentComponent {
  data: any[];
  isResultLoading = false;

  updateData(data: any[]) {
    this.data = data
  }
}

parent.component.html

<app-search-bar (change)="dataChange($event)" [(isResultLoading)]="isResultLoading"></app-search-bar>
<app-search [data]="data" *ngIf="!isResultLoading"></app-search>

update your Search.component.ts

//add outputs and inputs
@Output() change = new EventEmitter<any[]>(); //make sure to import EventEmitter from @angular/core
@Input() isResultLoading : boolean

// update searchResult  subscription function
searchResult(searchParam) {
  this.isResultLoading = true;
  this.http.get(`${environment.apiUrl}/Recherchetout.php`, { params: { search: searchParam } }).subscribe(
    (data: Array<any>) => {
      this.change.emmit(data);
      this.isResultLoading = false;
    }
  );
}

and finally instead of having observable result$ inside Search.component.ts replace it with @Input() data:Any[]

  • Related