Fala, Dev!


Uma observação para caso você tente executar o projeto no ambiente Web.


Tendo em vista a facilidado do Flutter em executar o mesmo código em diferentes plataformas, é bem simples para rodarmos também na Web. Para isso basta selecionar o navegador que queira na parte inferior direita do seu VS Code e depois teclar F5 e pronto! Seu projeto estará rodando na Web. Show!


Mas se você tentar fazer isso, pode acabar se deparando com este pequeno trecho que erro abaixo:


Error: You are trying to use contextless navigation without
a GetMaterialApp or Get.key.
If you are testing your app, you can use:
[Get.testMode = true], or if you are running your app on
a physical device or emulator, you must exchange your [MaterialApp]
for a [GetMaterialApp].


Mas pode não se preocupe que isso é bem simples de se resolver, mas antes vamos entender o porquê desse erro ter acontecido.


Este problema consiste na navegação que fazemos assim que o nosso app é iniciado. Lembra que quando o app é iniciado nós injetamos na memória o AuthController? Dentro do nosso AuthController estamos chamando o onInit (Método que é chamado sempre que a classe do tipo GetxController é instanciada) e dentro do onInit temos a chamada para a validação de token. Após isso estamos navegando ou para a tela de login ou para a tela home. O problema acontece porque essa nevagação tenta ocorrer antes mesmo do nosso GetMaterialApp ser corretamente carregado.


Entendo o motivo do problema vamos partir para a solução! :D


Abaixo vou te passar o passo a passo para resolvermos isso:


1 - Precisamos retirar o trecho de código do nosso AuthController que sempre que iniciado tenta validar o token. Pode tanto comentar quanto remover tudo:


...
class AuthController extends GetxController {
  
  // @override
  // void onInit() {
  //   super.onInit();
 
  //   validateToken();
  // }
...


2 - Em seguida, como removemos um trecho super importante para o correto funcionamento do app, precisamos encontrar uma outra forma de sempre que iniciarmos o app, possamos verificar e validar o token, mas desta vez em um lugar que temos a certeza que o GetMaterialApp já está carregado em se tratando do ambiente Web. Muito simples, na nossa tela SplashScreen!


Como esta tela possui uma classe Stateless, precisamos mudá-la para Stateful (Ctrl + . sobre o nome Stateless e selecionado "Convert to Stateful") e utilizar do auxílio do initState para que possamos fazer algo sempre que esta tela é iniciada;


...
class SplashScreen extends StatefulWidget {
  const SplashScreen({Key? key}) : super(key: key);
 
  @override
  State<SplashScreen> createState() => _SplashScreenState();
}
 
class _SplashScreenState extends State<SplashScreen> {
 
  @override
  void initState() { <=== MÉTODO QUE É CHAMADO SEMPRE QUE A TELA INICIA
    super.initState();
    
  }
...


3 - Já tendo a classe como uma Stateful e com a chamada do initState criada, basta que agora a gente busque o objeto do tipo AuthController que foi injetado na memória e em seguida a gente acione o método validateToken. Vai ficar desta forma:


...
@override
void initState() {
  super.initState();
 
  Get.find<AuthController>().validateToken();
}
...


Com isso resolveremos o problema ao executar no ambiente Web. :D


Espero que tenha gostado! Caso tenha qualquer problema ou dúvida fique à vontade para me enviar uma mensagem aqui no fórum. Bons estudos.