Quando o simples fica complicado
Explicando o problema
Bom, eu estava implementando uma timeline de programações no app do usuário, o mesmo ia poder clicar em início e fim de cada programação para poder cumpri-la se estivesse dentro do horário pré-estabelecido. A princípio era algo simples e fácil de fazer, boa parte do código já estava pronto e eu só precisei fazer umas simples modificações.
Acontece que tínhamos uma data de entrega e eu precisava que o back end me desse as rotas que precisava para adicionar uso a essa funcionalidade que eu tinha implementado, porém na correria deles, os caras me entregaram tudo na manhã da data limite…
A princípio eu não me desesperei, por mais que o prazo estivesse estourando, eu só precisava juntar o que eu tinha feito com o que os caras fizeram e pronto, tudo estaria ok, certo? Errado…
Esse dia foi louco, por mais simples que fosse, as coisas simplesmente não encaixaram, não funcionava, tínhamos um esquema de salvamento em memória local, para caso o cliente ficasse sem internet ele poderia ver qual programação ele deveria estar seguindo e o que tinha para fazer depois. O fluxo então era o seguinte:
Lógica
O usuário clica em INÍCIO
Avisamos a API que ele fez essa ação usando uma rota PUT
A API altera o valor da dataDeInicioDaAtividade e alimenta ela com a data exata de quando foi modificada
O app faz mais uma requisição na rota de programações, agora para pegar a variável descrita acima e ver se está tudo ok com ela, se ela tiver dados diferentes de null deveria desativar o botão INÍCIO e ativar o botão FIM, porque isso significa que aquela programação em específico já foi iniciada.
O mesmo acontecia para dataDeFimDaAtividade
A lógica era só essa e seria super simples implementar, porém eu havia esquecido de algo que citei acima, o salvamento em memória local…
Acontece que eu estava fazendo tudo isso, buscava as programações após a atualização e, usando um debugger, eu via que ela vinha com os dados corretamente alterados. Porém, na hora de mudar os botões para habilitado/desabilitado na interface do usuário, simplesmente não funcionava. Usando a inspeção de cada widget, eu via que os valores de dataDeInicioDaAtividade e dataDeFimDaAtividade sempre vinham nulos nesse caso…
Tínhamos uma regra onde pegávamos as programações do controller (salvas em memória) e passávamos para elas os dados que vinham da API, mas quando isso acontecia, a tela já tinha sido rebuildada e não funcionava também…
Solução
Quebrei a cabeça por muito tempo até perceber uma coisa: sempre que buscávamos as novas programações na API, verificávamos se os IDs eram iguais aos que já tínhamos salvo antes. Se fossem iguais, não atualizávamos os valores na memória local. Isso porque a ideia desse formato de atualização tinha vindo depois e eu já era o terceiro programador a mexer nesse código… Sendo assim, a gente não exibia na tela os cards novos da programação quando recarregávamos, ou quando saíamos e voltávamos para a tela. O que mostrávamos era apenas a versão inicial salva na memória do dispositivo. E quando reiniciávamos o app e entrávamos de novo, ele recarregava isso e mostrava a versão da nuvem…
Até perceber isso, queimei muitos miolos, pensei que fosse problema no DateTime do Flutter, que o formato UTC não estava sendo válido e muitas outras coisas. Mas no final do dia, depois de quase 10 horas nessa tarefa, adicionei UMA linha de código no meu trabalho anterior e… funcionou.
Explicando a solução, essa única linha de código foi adicionada logo após o recebimento e validação dos dados vindos da API. Ela limpava a variável local com as programações salvas e atribuía o novo valor, recebido da API. Isso resolvia todo o problema anterior que já expliquei…
_programacoesSalvasEmMemoria.clear();