2
respostas

Erro na busca do Ionic

Estou desenvolvendo um app e preciso criar um sistema de busca nele. Segui a documentação oficial e cheguei ao seguinte resultado:

Template

<ion-searchbar class="searchbar-input" (ionInput)="getItems($event)"></ion-searchbar>

<div class="tile" *ngFor="let item of produtos">
          <div class="item">
            <div class="tile__media">
              <img src="{{item .imagem}}" (click)="selecionaProduto(item )">
            </div>
            <span>R$ {{ item .precoDe.toFixed(2).toString().replace(".", ",") }}</span>
            <h3>R$ {{ item .precoPor.toFixed(2).toString().replace(".", ",") }}</h3>
            <p>{{ item .nome }}</p>
            <img src="assets/imgs/adicionar.png" (click)="adicionaProduto(item )">
          </div>
        </div>

Controller

public produtos() {
    this.storage.get('token').then( (token) => {
      this._data.get(token, 'products/1/6')
        .then(resposta => {
          this.produtos = resposta
          this.initializeItems()
        }).catch(err => {
          console.error(err)
        })

    })
  }
getItems(ev: any) {
    this.initializeItems()

    const val = ev.target.value

    if (val && val.trim()) {
      this.items = this.items.filter(
        item => item.toString().toLowerCase().includes(val.toString().toLowerCase())
      )
    }
    if (val && val.trim() != '') {
      this.produtos = this.produtos .filter((item) => {
        return (item.toLowerCase().indexOf(val.toLowerCase()) > -1)
      })
    }
  }
public initializeItems() {
    this.produtos = this._data.filterItems(this.searchTerm)
  }

Funciona perfeitamente com lista estática, mas quando insiro os dados da API, como no exemplo da produtos(), dá erro dizendo que this.produtos .filter não é uma função.

Alguém poderia dar uma luz?

2 respostas

Boa noite, Rodrigo! Como vai?

Esse problema não é nem relacionado ao Ionic! O que deve estar acontecendo é que vc chama o método getItems() sem que a lista de produtos esteja preenchida. Isso acontece pq o JavaScript tem comportamento assíncrono, por isso disse no início que não é um problema relacionado ao Ionic! E, se vc reparar, é justamente uma operação assíncrona que vc faz no método produtos()! Tanto é verdade que vc teve que utilizar Promise pra resolver essa questão de assincronicidade.

Ou seja, pra resolver esse problema, vc tem que fazer a chamada do método getItems() apenas quando tiver certeza que o método produtos() já tiver terminado de fazer sua tarefa.

Obs.: No desenvolvimento Ionic a boa prática é utilizar Observables em vez de Promise, uma vez que o primeiro é o padrão de solução de questões assíncronas dado pelo Angular 2+.

Qualquer coisa é só falar!

Grande abraço!

Olá professor

Eu editei o produto e adicionei o template. O método getitem() é chamado no template, no ion-search. Mas o que você falou me alertou de que o método initializeItems() é desnecessário, já que recebo os dados da API no método getProdutos().

Fiz uma limpeza no código e cheguei na solução abaixo:

constructor(
    public navCtrl: NavController,
    private _data: DataProvider,
    private storage: Storage
) {
    this.getProduts()
  }

public produtos() {
    this.storage.get('token').then( (token) => {
      this._data.get(token, 'produtos')
        .then(resposta => {
          this.produtos= resposta
        })
        .catch(err => {
          console.error(err)
        })

    })
  }

  public getItems(ev: any) {
    this.produtos()

    const val = ev.target.value
    console.log(val)

    if(val && val.trim() != '') {
      this.produtos= this.produtos.filter((item) => {
        console.log(item)
        return (item.nome.toLowerCase().indexOf(val.toLowerCase()) > -1)
      })
    }
  }

Dessa maneira o código funciona perfeitamente no console, mostrando os valores digitados(val) e o resultado da busca (item). Porém, no app ele faz a busca, mostra os itens buscados, mas logo em seguida retorna novamente para a lista completa, não mantendo o resultado da busca por mais de um segundo.

O template está assim:

<ion-searchbar class="searchbar-input" (ionInput)="getItems($event)"></ion-searchbar>

<div class="tile" *ngFor="let item of produtos">
          <div class="item">
            <div class="tile__media">
              <img src="{{item.imagem}}" (click)="selecionaProduto(item)">
            </div>
            <span>R$ {{ item.precoDe.toFixed(2).toString().replace(".", ",") }}</span>
            <h3>R$ {{ item.precoPor.toFixed(2).toString().replace(".", ",") }}</h3>
            <p>{{ item.nome }}</p>
            <img src="assets/imgs/adicionar.png" (click)="adicionaProduto(item)">
          </div>
        </div>

Pode me mostrar onde estou errando?

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software