1

I want to search in my table but I want the table to be filled with my data to start with. Currently, it will only be filled once I start typing in the search bar.

I think the problem is coming from that the productsArray is empty when the component is initialized

My data is coming from a JSON file in the project.

Below you can see what I currently have

export class TableComponent implements OnInit {
      searchText: any;
      productsArray: Products[] = [];
      filteredArray = [...this.productsArray];

      constructor(private http: HttpClient) {}

      ngOnInit(): void {
        this.getProducts().subscribe((res) => {
          this.productsArray = res;
        });
      }
      getProducts(): Observable < Products[] > {
        return this.http
          .get < any > ('assets/mock.data.json')
          .pipe(map((results) => results.data));
      }
      filterArray(): any {
        if (!this.productsArray.length) {
          this.filteredArray = [];
          return;
        }

        if (!this.searchText) {
          this.filteredArray = [...this.productsArray];
          return;
        }

        const products = [...this.productsArray];
        const properties = Object.keys(products[0]);

        this.filteredArray = products.filter((product) => {
          return properties.find((property) => {
              const valueString = product[property].toString().toLowerCase();
              return valueString.includes(this.searchText.toLowerCase());
            }) ?
            product :
            null;
        });
      }
    }
Code Name Category
<tbody *ngFor="let product of filteredArray; let i = index">
  <tr>
    <td>{{ product.code }}</td>
    <td>{{ product.name }}</td>
    <td>{{ product.category }}</td>
  </tr>
</tbody>
1
  • Just call filterArray also within the subscription callback after you assigned this.productsArray to apply an initial filter. Commented May 17, 2021 at 13:01

2 Answers 2

2

When filteredArray is initialized, it was empty. The filteredArray is filled with some value only when filterArray() is called. So provide the value for filteredArray in ngOnInit(). Try this:

ngOnInit(): void {
    this.getProducts().subscribe((res) => {
      this.productsArray = res;
      this.filteredArray = [...this.productsArray];
    });
  }
Sign up to request clarification or add additional context in comments.

Comments

0

you need to use a pipe, some like this

@Pipe({
    name: 'filterPipe'
})
export class FilterPiper implements PipeTransform {
    transform(array: any[], properties: any[], filter: string) {
        if (!array) {
            return [];
        }
        if (!properties.length || !filter) {
            return array;
        }

        filter = filter.trim().toLowerCase();
        return array.filter((element) => 
      !!(properties.find((property) => {
          const valueString = product[property].toString().toLowerCase();
          return valueString.includes(filter)
        )) 
    });
}

and in the html

 <tbody *ngFor="let product of productsArray | filterPipe: propertiesArray : searchText ; let i = index">
  <tr>
    <td>{{ product.code }}</td>
    <td>{{ product.name }}</td>
    <td>{{ product.category }}</td>
  </tr>
</tbody>

remember the pipe needs to be declarated in a module and imported in your component

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.