3
respostas

Botões para contagem de clicks com Ionic

Tenho uma sequencia de botões no aplicativo para contagem de veículos em rodovias, para cada click é criado um array JSON com o contador somando mai 1 ao índice correspondente ao botão.

Código HTML

<ion-col>
        <ion-button id="auto" class="div" (click)="contador('auto')" color="tertiary"> 
        Auto <br> ({{contados('auto')}})
        </ion-button>
      </ion-col>

      <ion-col>          
        <ion-button id="utilitario" class="div utilitario"  (click)="contador('utilitario')" color="tertiary">
          Auto <br> Utilitario <br> ({{contados('utilitario')}})    
        </ion-button>  
      </ion-col>

Código TypeScript

constructor(private storage: Storage )  {
   this.count= {
      date: '',
      time: '',
      auto: 0,
      utilitario: 0,
    };

    this.conta = this.count;

}

  contador(tipo: string){

      var b = document.getElementById(tipo); 
      b.setAttribute("disabled", "true");

    this.storage.get("listaForm").then((val: any) => {
        this.count[tipo]++;
        this.conta[tipo]++;

        let array: any[] = [];
        if (val !== "") {
          array = array.concat(JSON.parse(val));

        }

          let date: any;
          let time: any;

          let dataCompleta = new Date(),
              horaCompleta = new Date();

          let dia = this.formataZerosEsquerda(dataCompleta.getDate()),
              mes = this.formataZerosEsquerda((dataCompleta.getMonth() + 1)),
              ano = dataCompleta.getFullYear(),
              hora = this.formataZerosEsquerda(horaCompleta.getHours()),   
              minutos = this.formataZerosEsquerda(horaCompleta.getMinutes()),
              segundos = this.formataZerosEsquerda(horaCompleta.getSeconds()),
              milisegundos = this.formataZerosEsquerda(horaCompleta.getMilliseconds());

          date = dia + "/" + mes + "/" + ano;
          time = hora + ":" + minutos + ":" + segundos + ":" + milisegundos;         

          this.count["date"] = date;
          this.count["time"] = time;

          array.push(this.count);

      this.storage.set("listaForm", JSON.stringify(array)).then((data: any) => {
        this.limpaCount();
        this.storage.set("historico", this.conta).then((val: any) => {
          console.log(data);

          b.setAttribute("disabled", "false");
        });

      });

    });
  }

 contados(tipo: string){

    return this.conta[tipo];
  }

limpaCount(){
    this.count.date= '';
    this.count.time= '';
    this.count.auto= 0;
    this.count.utilitario= 0;
}

O contador funciona porém caso dois botões sejam clicados quase que simultaneamente os dois clicks são registrados no mesmo índice do array.

Como os dados estão vindo ao clicar em dois botões: [{"date":"29/04/2020","time":"10:05:31:09","auto":1,"utilitario":1}]

Como deveriam vir mesmo clicando em dois botões: [{"date":"29/04/2020", "time":"10:05:31:09", "auto":1, "utilitario":0}] , [{"date":"29/04/2020", "time":"10:05:31:09", "auto":0, "utilitario":1}]

O processamento da função contador está mais lento que o click do usuário

3 respostas

Não é que esteja mais lento, é um problema de assincronia, o seu storage.get não vai estar disponível de imediato ao clique e por isso usamos o then, então, os cliques acontecem antes do then poder ser executado, o que faz com que a contagem seja calculada como uma só.

Algo que acho que resolveria, seria isolar cada click em uma Promise, assim, cada clique criaria seu próprio contexto de execução que faria o storage.get e computaria o valor ao final.

Obrigado pela dica!!

Sou iniciante na área, poderia me dar algum exemplo de como fazer isso? não sei por onde começar...

Recomendo dar uma olhada nos cursos de JavaScript Avançado I, II e III, para se aprofundar mais no javascript.

Tem a documentação também que vou deixar linkada aqui: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise

Mas vamos fazer um teste rápido para ver se o problema pode ser resolvido de outra forma, até mais simples.

Isola seu código em uma função auto-executável.

contador(tipo: string) {
    ((tipo) => {
        // seu código aqui
    })(tipo);
 }

Eu confesso que acho seu código muito complexo