geraktOfRivia
geraktOfRivia

Reputation: 355

How to create a search filter in date ranges with Angular?

Greetings SO community.

I'm trying to create a date range filter pipe in Angular, fetching data from an API but It doesn't work because it filters all data and doesn't show any.

I'm fetching the data from firebase https://loggin-app-fa0a7.firebaseio.com/data/facturas.json

This is the service where I'm fetching the data

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class FacturasService {

  constructor(private http: HttpClient) { }

  getFacturas() {
    return this.http.get('https://loggin-app-fa0a7.firebaseio.com/data/facturas.json');
  }


}

Then I have this pipe to filter the data by a date range

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filtroFecha'
})
export class FiltroFechaPipe implements PipeTransform {

  transform(row: any, f1: Date, f2?: Date): any {

    const resultadoFiltro = [];
    // si es menor a la fecha final
    if (f1 >= f2 || f1 == null) {
      return row;
    }
    // si el argumento de fecha final es invalido, se setea a la fecha actual
    if (f2 == null) {
      f2 = new Date();
    }
    // si ambos arreglos son correctos entonces se crea el nuevo arrego
    for (const filteredRow of row) {
      if (row.fecha >= f1 && row.fecha <= f2) {
        resultadoFiltro.push(filteredRow);
      }
    }
    return resultadoFiltro;


  }

}

and this is the component where I try to apply the pipe

   import { Component, OnInit } from '@angular/core';
import { FacturasService } from '../../services/facturas.service';


@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {

  desde = new  Date('December 25, 1995 13:30:00');
  hasta =  new Date();

  // almacena facturas
  facturas: any = [];

  constructor(private ventas: FacturasService) { }


  ver() {
    console.log('desde:', this.desde);
    console.log('hasta:', this.hasta);
  }

  ngOnInit() {
    this.ventas.getFacturas().subscribe((data: any) => {
      this.facturas = data;
      console.log('Facturas works');
      console.log('================');
      console.log(this.facturas);
    });
  }
}

And here the template

 <!-- Header  -->
  <div class="my-auto">
    <div class="row d-flex justify-content-center mt-2 animated fadeIn">
      <p class="h1">Facturas Resientes</p>
    </div>
    <!-- Header  -->

    <!-- filtros -->
    <div class="row d-flex mt-3">

        <!-- date time picker component -->
        <form #myForm="ngForm" novalidate class="col-6">
             <input type="date"  [(ngModel)]="desde" name="desde">
      </form>

      <form #myForm="ngForm" novalidate class="col-6">
        <input type="date"  [(ngModel)]="hasta" name="hasta">
    </form>

    </div>

<div class="row mt-3">
  <button   class="btn btn-danger" (click)="ver()">Ver Fecha en consola</button>
</div>


  <!-- filtros -->

    <!-- tabla de clientes -->
    <div class="row card animated fadeIn mt-3" id="agenda">
      <table class="table table-borderless">
        <thead>
          <tr>
            <th scope="col">Empresa</th>
            <th scope="col">Monto</th>
            <th scope="col">Estado</th>
            <th scope="col">Fecha</th>
          </tr>
        </thead>
        <tbody>
          <!-- aplicando el pipe al ng-fo -->
          <tr *ngFor="let factura of facturas |filtroFecha:desde :hasta">
            <td>{{factura.empresa}}</td>
            <td>{{factura.monto | currency}}</td>
            <td>{{factura.estado}}</td>
            <td>{{factura.fecha | date}}</td>
          </tr>
        </tbody>
      </table>
   <!-- tabla de clientes -->

and this is the data from firebase

    [
    {
        "empresa": "Wallmark",
        "estado": "pendiente",
        "fecha": "Thu May 28 03:19:43 UTC 2020",
        "monto": 2000
    },
    {
        "empresa": "Corte Ingles",
        "estado": "pendiente",
        "fecha": "Thu May 22 03:19:43 UTC 2020",
        "monto": 2345555
    },
    {
        "empresa": "innovatek",
        "estado": "pagada",
        "fecha": "Thu May 28 03:19:43 UTC 2020",
        "monto": 300000
    },
    {
        "empresa": "holeee",
        "estado": "pagada",
        "fecha": "Thu May 28 03:19:43 UTC 2020",
        "monto": 790000
    },
    {
        "empresa": "everlast",
        "estado": "pagada",
        "fecha": "Thu May 28 03:19:43 UTC 2020",
        "monto": 568999
    }
]

but the pipe filters all the data and it doesn't show in the view I've created this kind of pipes before but not for a Date type

Here is my project

https://stackblitz.com/edit/github-necjgp?file=src%2Fapp%2Fservices%2Ffacturas.service.ts

I hope you can help me SO comunity :(

Upvotes: 1

Views: 6178

Answers (2)

Cagri Tacyildiz
Cagri Tacyildiz

Reputation: 17610

DemoI have seen several problems. one is in for loop u need to write filteredRow rather than row another is missing convert date should be like new Date(filteredRow.fecha). As I seen some problems also while adding removing date.

Then used filter method rather than for loop and pushing to new one and put some controls to remove click of date input.

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'filtroFecha'
})
export class FiltroFechaPipe implements PipeTransform {
  transform(row: any, f1: Date, f2?: Date): any {
    f1.toString().length == 0 ? f1 = new Date("1995-12-25T11:30:00.000Z") : f1;
    f2 == null ? f2 = new Date() :f2; 
    if (f1 >= f2 || f1 == null) { return row;}
    return row.filter(x=>{return  new Date(x.fecha) >= new Date(f1) && new Date(x.fecha) <= new Date(f2)});   
  }
}

Upvotes: 1

i changed your Pipe to this:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filtroFecha'
})

export class FiltroFechaPipe implements PipeTransform {

  transform(row: any, f1: Date, f2?: Date): any {

const resultadoFiltro = [];
let date1 = new Date(f1);
let date2 = new Date(f2);
// si es menor a la fecha final
if (f1 >= f2 || f1 == null) {
  return row;
}
// si el argumento de fecha final es invalido, se setea a la fecha actual
if (f2 == null) {
  f2 = new Date();
}
// si ambos arreglos son correctos entonces se crea el nuevo arrego
for (const filteredRow of row) {
  let a = new Date(filteredRow.fecha);
  console.log(a);

  if (a > date1 && a <= date2) {
    console.log("asd", filteredRow);
    resultadoFiltro.push(filteredRow);
  }
}
return resultadoFiltro;
  }
}

And now it works! It was missing the new Dates() so it was comparing strings.

Upvotes: 1

Related Questions