Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Como ordenar dados carregados do storage

Boa noite.

Tenho uma dúvida, sobre a ordenação de dados do storage.

Criei uma API que retorna alguns dados (id, dados em geral, data e etc), quando eu carrego os dados eles vem ordenados corretamente pela data e faço a inserção dos mesmos no storage.

Ao recuperar esses dados para listá-los na view:

return this._storage.forEach((value, key, index) => {
            if (key.indexOf('fatura') >= 0) {
                let fatura = new Fatura(
                    value.ordem,
                    value.idestab,
                    value.documento,
                    value.parcela,
                    value.serie,
                    value.valor,
                    value.vencimento,
                    value.desconto);

                    console.log(fatura);

                faturas.push(fatura);
            }
        })
        .then(() => faturas);

Os registros não vem na ordem, que foram inseridos.

Minha dúvida são duas na verdade:

1 - Como ele trata a ordenação? É pela key que eu defini no momento da gravação?

private _getKey(fatura: Fatura) {
        return "fatura" + fatura.idestab + fatura.documento + fatura.parcela + fatura.serie;
    }

2 - Após uma série de tentativas decidi criar um campo ordem e estou enviando o índice dos registros que gravo junto com o que veio da API, mesmo assim a ordenação funciona baseada em String, ou seja: 1, 10, 11, 12..., 19, 2, 20, 21... Como eu poderia ordenar e como funciona isso?

Eu li esta documentação do Angular: https://angular.io/guide/pipes Mas eles mesmos não recomendam utilização de Pipes.

Obrigado desde já.

2 respostas
solução!

Oi Guilherme, vc ta falando do localStorage, certo?

Então, ele não tem ordem definida. Você não pode contar com ele vir numa certa ordem. Isso depende de implementação e não há nenhuma garantia.

Dito isso, suas opções é salvar a ordem junto com os registros ou fazer a ordenação no código de alguma forma.

Dependendo do seu modelo, se forem poucos dados, o que é muito comum é salvar todos os dados num único registro com json serializado. Ou seja, ao inves de ter um registro pra cada objeto, vc salva tudo num registro só com um array de objetos em formato json. Aí vc coloca a ordem que vc quiser.

Se isso nao for uma opcao (pq vc precisa acessar registros individualmente e salvar tudo junto é custoso), vc pode criar uma coluna a mais com a ordem como vc fez (ou ate criar um registro separado que mantem uma lista de keys em ordem por exemplo).

Por fim, o problema que vc teve com o sort que ordena string e não numero é um saco mesmo no JS. A solucao é simples, porem. Bloguei sobre isso um tempo atras:

http://blog.alura.com.br/ordenacao-de-numeros-no-javascript-nao-funciona/

Sérgio, entendi sobre o localStorage, era isso mesmo.

E sobre o .sort() também ficou mais claro, acabei induzido pela minha própria pesquisa a ir por um caminho totalmente errado e mais complexo.

Tentei com o .sort() logo de cara, como ordenou errado eu pesquisei e o primeiro link (https://forum.ionicframework.com/t/order-a-list/55389) e mais outros na mesma pesquisa, falavam de pipes. Imaginei que teria que seguir por este caminho e até acabei resolvendo com ele.

@Pipe({name: 'orderBy'})
export class OrderByPipe implements PipeTransform {
  transform(value: Array<any>, field: string): any {
    if(value == null) {
      return null;
    }
    if (field.startsWith("-")) {
      field = field.substring(1);
      if (typeof value[field] === 'string' || value[field] instanceof String) {
        return [...value].sort((a, b) => b[field].localeCompare(a[field]));
      }
      return [...value].sort((a, b) => b[field] - a[field]);
    }
    else {
      if (typeof value[field] === 'string' || value[field] instanceof String) {
        return [...value].sort((a, b) => -b[field].localeCompare(a[field]));
      }
      return [...value].sort((a, b) => a[field] - b[field]);
    }
  }
}

Mas agora o seu post deixou bem mais claro.

Obrigado.