Brandon Franco
Brandon Franco

Reputation: 53

Ionic 4 Filter JSON by multiple values

Currently I've been facing an issue when it comes to filtering a local JSON file by multiple criteria. I originally thought this would be a simple fix where you could just club multiple conditions using and(&&). However, whenever the data is loaded to the Ngx-Datatable, nothing is appearing. The filtering has been working with a single condition, which is why I find it really odd that multiple criteria is not working. Could it possibly be an issue with the JSON file? Do I have to use another method to do this? Or is it the way I'm loading the data view? I'm really curious as to why this isn't working as I figured that .filter() could handle the multiple criteria as it has been working with the single condition provided before.

TypeScript File

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import data from './../../assets/pathrequests.json';
import { NavController } from '@ionic/angular';
import { NavigationExtras } from '@angular/router';
import { AlertController } from '@ionic/angular';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';


@Component({
  selector: 'app-view-necropsy-details',
  templateUrl: './view-necropsy-details.page.html',
  styleUrls: ['./view-necropsy-details.page.scss'],
})
export class ViewNecropsyDetailsPage implements OnInit {

  pathrequestid: string;
  procedureid: string;
  requestdate: string;
  animalqty: string;
  marker: string;
  method: string;
  fixative: string;
  handling: string;
  processing: string;

  items: any[];
  private pathrequests: any[] = data;
  tablestyle = 'bootstrap';


  constructor(private alertCtrl: AlertController, private http: HttpClient, private route: ActivatedRoute, private router: Router, public navCtrl: NavController) { }

  ngOnInit() {
    this.route.queryParams.subscribe(params => {
      this.pathrequestid = params["pathrequestid"];
      this.procedureid = params["procedureid"];
      this.requestdate = params["requestdate"];
      this.animalqty = params["animalqty"];
      this.marker = params["marker"];
      this.method = params["method"];
      this.fixative = params["fixative"];
      this.handling = params["handling"];
      this.processing = params["processing"];
    });
    this.loadData();
  }

  loadData(){
    let data:Observable<any>;
    data = this.http.get('assets/tissue.json');
    data.subscribe(data => {
      this.items = data.filter(item => item.pathrequestid === this.pathrequestid && item.procedureid === this.procedureid);
      console.log(this.items);
    })
  }

}

HTML Template

<ion-header>
  <ion-toolbar color="primary">

    <ion-buttons slot="start">
      <ion-menu-button menu ="main-menu"></ion-menu-button>
    </ion-buttons>

    <ion-buttons>
      <ion-back-button defaultHref="/view-procedure"></ion-back-button>
    </ion-buttons>

     <ion-buttons class="button_style"  slot="end">
      <ion-button (click)="switchStyle()">
        {{ tablestyle }}
      </ion-button>
    </ion-buttons>

  </ion-toolbar>
</ion-header>


<ion-content>
  
  <ngx-datatable  class="necropsydetails_table"
    [ngClass]="tablestyle" 
    [rows]="items"
    [columnMode]="'force'" 
    [headerHeight]="60" 
    [rowHeight]="'auto'">
 
    <ngx-datatable-column name="tissue"></ngx-datatable-column>
    <ngx-datatable-column name="collectflg"></ngx-datatable-column>
    <ngx-datatable-column name="weighflg"></ngx-datatable-column>
    <ngx-datatable-column name="photoflg"></ngx-datatable-column>
    <ngx-datatable-column name="tissuecomment"></ngx-datatable-column>

  </ngx-datatable>


</ion-content>

Upvotes: 1

Views: 767

Answers (2)

cjd82187
cjd82187

Reputation: 3593

Your filter should work, but you may have a race condition, or bad parameters. this.procedureid is set in the queryParams async call, but load data is called synchronously but also calls an async function (the http get).

If you move the call to this.loadData() inside the subscribe, that should make sure the data.

  ngOnInit() {
    this.route.queryParams.subscribe(params => {
      this.pathrequestid = params["pathrequestid"];
      this.procedureid = params["procedureid"];
      this.requestdate = params["requestdate"];
      this.animalqty = params["animalqty"];
      this.marker = params["marker"];
      this.method = params["method"];
      this.fixative = params["fixative"];
      this.handling = params["handling"];
      this.processing = params["processing"];
      // calling it now will at least make sure you attempted to set the data from params, but double check the params are actually returning data as well.
      this.loadData();
    });
    // calling it here will execute before the above code
    // this.loadData();
  }

You can get more sophisticated with other RxJS operators, but this is a simple enough case it may not be worth complicating it just yet.

Upvotes: 0

Kevin Oane
Kevin Oane

Reputation: 11

We may rule out the filter as it works. Please post the template as well to aid other viewers.

Given the info available, it may be with the model or template; sometimes needing poking the framework to forcibly render (i.e. Change detection in Angular). I could suggest:

  1. Delaying showing the results view until items is assigned.

  2. Moving the filter inside a pipe and use the async pipe to display the already-filtered data. Items would need to be an Observable though.

     this.http.get('assets/tissue.json')
     .pipe(filter(item => /*criteria here*/)
    

then on the template

    *ngFor="let item of items | async"

Hope these help.

Upvotes: 1

Related Questions