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

Erro ao direcionar o lazy loading angular

Estou com problemas. Ao submeter um formulário em Login component e direcionar para /home, faz o redirecionamento mas, volta ao LoginComponent. Na barra de endereços ao submeter troca para uma /? abre o component e redireciona para a página inicial.

Nessa parte está o roteamento

import {RouterModule, Routes} from '@angular/router';
import {NotFoundComponent} from './errors/not-found/not-found.component';
import {NgModule} from '@angular/core';
import {LoginComponent} from './login/login.component';

const routes: Routes = [
  /*// Lazy loading. Carregar partes do projeto conform o usuário utiliza
  // PathMatch vai considerar apenas o caminho e não todos os subsequentes. Ex; user/userid/userfull apenas user
  {path: '', pathMatch: 'full', redirectTo: 'home'},
  {path: 'home', loadChildren: './home/home.module#HomeModule'},*/
  {path: '', component: LoginComponent},
  {path: '', redirectTo: 'home', pathMatch: 'full'},
  {path: 'home', loadChildren: './home/home.module#HomeModule'},
  {path: '**', component: NotFoundComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {

}

Esse é o roteamento do HomeComponent

import {RouterModule, Routes} from '@angular/router';
import {HomeComponent} from './home.component';
import {NgModule} from '@angular/core';

const routes: Routes = [
  {path: '', component: HomeComponent}
  ];

@NgModule({
  // Mudar para forChild
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class HomeRoutingModule {}

Aqui o código HomeModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HomeComponent } from './home.component';
import {RouterModule} from '@angular/router';
import {HomeRoutingModule} from './home.routing';

@NgModule({
  imports: [
    CommonModule,
    RouterModule,
    HomeRoutingModule
  ],
  declarations: [HomeComponent],
  exports: [HomeComponent]
})
export class HomeModule { }

AppModule

import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {NgModule} from '@angular/core';

import {AppComponent} from './app.component';
import {AppRoutingModule} from './app.routing';

import {ErrorsModule} from './errors/errors.module';
import {LoginModule} from './login/login.module';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    LoginModule,
    ErrorsModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

AppComponentHtml

<router-outlet></router-outlet>
19 respostas

Há um guard de rotas que ao submeter para a rota / , no lugar dele exibir o componente de login ele redireciona para a timeline do usuário. Chuto que sua guard esta com problema. Porque, se você joga para a home após o login, com certeza ele vai exibir o login novamente, por isso a importância dessa guarda de rota.

Compartilhe seu código de SigninComponent, o arquivo de rotas do módulo Home. Você pode ainda baixar o arquivo do projeto completo e verificar como estão suas rotas.

Bom dia Flavio. O meu projeto está sem o Guard para a(s) rota(s). Tentei de alguns jeitos. Vi o exemplo de lazy loading no angular.io e tentei simular mas, sem chance de acertar. Tentei mudar o seu exemplo no curso para iniciar uma aplicação minha. Mas só tem a página de login que dentro dela tem um form que ao submeter vai para home. No home só tem o padrão criado pelo CLI e adicionado a módulo de roteamento nela. Seria pedir demais um exemplo da seguinte forma. Não tem precisa ter nada dentro dos components. A página principal direciona para login. e aí o lazy loading para home e dentro de home o roatamento para qualquer outro feature module. Aí ainda dentro da principal feature module com a mesma ideia do HomeModule? Seria quase o do angular IO. Mas, diferente com essas subrotas e o LoginComponent. Se for possível. Pq nessa aplicação que estou criando estou testando apenas partes do curso para aí fazer uma aplicação mesmo. O projeto do curso fiz ele todo. E está 100% mas, depois sempre quando termina tento inventar essas coisas e possibilidades pra fixar o que aprendo. Uso sempre eles como base.

Nao é o projeto do curso, entendi. Estou com muita dificuldade para entender o que você quer, porque no curso pelo o que eu entendi eu já faço isso tudo.

Sugiro você fazer lazy loading só depois de fazer seu login funcionar. Faz funcionar como você espera é depois implementa o lazy loading. Assim você consegue isolar o problema. Veja que nem o exemplo do Angular.io você conseguiu fazer funcionar, então isolar as partes vai lhe ajudar.

Fazer primeiro sem lazy loading lançará o foco nas suas rotas, como você deseja que fique. Estando tudo funcionando, dai vc entra com o lazy loading que tem que continuar com o mesmo comportamento.

Vi também que seu HomeRoutingModule não tem children! Veja que na aula eu adiciono children e outros detalhes. Outra coisa que você pode fazer é arquitetar suas rotas para que façam mais sentido, separando bem as coisas.

Entendi. O que eu fiz. Resumindo. Criei uma LoginModule não está usando autenticação e nem nada por enquanto. É só um template que quando clica em login direciona para o HomeModule. Dentro do HomeModule só tem o component com o padrão Home works.

Aí fui fazer a ideia de separar por lazyLoading. Mas a parte inicial eu quero sempre que carregue o LoginComponent e somente depois 'submeter ' esse formulário direcione para HomeComponent.

Aí ficou a dúvida, porque a ideia seria ir criando módulos de funcionalidades depois de entrar em HomeComponent que vai estar em uma navbar e ir carregando eles conforme o usuário clicar nos menus dessa navegação.

Mas ao fazer o submit do fomulário onde o botão direciona para esse módulo que dá problema. coloca o sinal de ? entra no component e volta na tela inicial. Mas se digitar o /home o component carrega normal (Home works). Se quiser dar uma olhada. Posso compactar o arquivo e enviar.

Então...faz as rotas funcionarem sem lazy loading (Para vc se entender com elas). Fazendo isso e funcionando a navegação pós login, parte para o lazy loading. Dai se der pau você saberá que é no lazy loading e não na organização de suas rotas.

E como você está fazendo a navegação pelo login ?

Posta o código?

Isso. É como estou fazendo. Testei novamente. Retirei o lazy loading e fiz direto os componentes e foi.

import {RouterModule, Routes} from '@angular/router';
import {NotFoundComponent} from './errors/not-found/not-found.component';
import {NgModule} from '@angular/core';
import {LoginComponent} from './login/login.component';
import {HomeComponent} from './home/home.component';

const routes: Routes = [
  {path: '', component: LoginComponent},
  {path: 'home', component: HomeComponent},
  {path: '**', component: NotFoundComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {

adicionei no AppModule esses módulos e dentro do home retirei o módulo de rota.

aqui parte do layout do loginComponent.

          <div class="card-body ">
            <form (submit)="login()">
              <!--user-->
              <div class="input-group mb-3 input-group-lg">
                <div class="input-group-prepend">
                  <span class="input-group-text" id="userid"><i class="fa fa-user"></i></span>
                </div>
                <input type="text" pInputText autocomplete="false" class="form-control" placeholder="Usuário"
                       aria-label="Username" aria-describedby="userid">
              </div>
              <!--password-->
              <div class="input-group mb-3 input-group-lg">
                <div class="input-group-prepend">
                  <span class="input-group-text" id="passwordid"><i class="fa fa-lock"></i></span>
                </div>
                <input type="password" pInputText autocomplete="off" class="form-control" placeholder="Senha"
                       aria-label="Username" aria-describedby="passwordid">
              </div>
              <!--submit-->
              <div class="text-right btn-block mt-3">
                <button type="submit" class="btn btn-lg mv-btn mv-btn-info mb-0">ACESSAR</button>
              </div>
            </form>

e parte do LoginComponent.ts que faz a navegação.

import {Component, HostListener, OnInit} from '@angular/core';
import {PlatformDetectorService} from '../core/platform-detector/platform-detector.service';
import {Router} from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

 .........

  login() {
    this.router.navigate(['home']);
  }
}

HomeComponentHtml

<p>
  home works!
</p>

Assim está funcionando tranquilamente. Só o lazy que estou fazendo algo errado e não consegui identificar ainda.

Se subir no github fica mais fácil. Sobe desse jeito.

vou subir ele lá

Na sua solução inicial você tinha rotas iguais para login e home. A rota do login se não me engano tem que ter pathmatch full(É ser á primeira), caso contrário uma rota como/home vai disparar a rota do login porque começa com /. O pathmatch full faz a comparação exatamente igual. Não é aquele reditect que deve ter.

Quando estiver no meu computador eu testo seu exemplo (olhando assim, ele parece esta correto, só vou verificar cada parte).

Ainda hoje vejo lá. Digitar no smartphone é tenso. Faço uma revisão completa do assunto.

https://github.com/Faqtt0/LazyLoading

Muito obrigado. Desde já. Deixei a outra dúvida em comentário na rota central. Pois respondendo a primeira a segunda vai matar a minha outra dúvida que é simples. Desde já agradeço e vou continuar vendo fóruns aqui na net.

Tranquilo. Fique sossegado, eu resolvio isso. Só preciso estar no meu computador porque digitar código pelo smartphone e complicado e acabo sintetizando as respostas. Eu já sei o problema.

solução!

Fala meu aluno! O problema não tem relação com lazy loading nem com rotas! Vou explicar o que esta acontecendo!

Repare que ao submeter o formulário, o método login() ao ser chamado esta fazendo sua página recarregar! Isso mesmo! Ela recarrega e por isso você vê a home por alguns segundos e depois volta para login, porque volta para página principal. Esse é o problema.

O problema acontece porque seu form não é gerenciado por um FormGroup do módulo ReactiveFormModule e não sendo um formulário Reactivo, quando você executa o evento submit, o angular não sabe que é para chamar event.preventDefault() por debaixo dos panos e faz com que a página recarregue durante a submissão.

Se você não quiser usar o ReactiveFormModule (um FormGroup) para seu formulário, pode fazer assim:

<!-- no seu template -->
<form (submit)="login($event)">

E no seu método:


  login(event) {
    event.preventDefault();
    this.router.navigate(['home']);
  }

É a mesma coisa com JavaScript puro! :)

Mas você não precisará fazer isso se fizer a recomendação que vou lhe dizer agora.

Toda vez que for usar um formulário, seja reativo ou não, importe FormsModule. Ao importar esse módulo, o Angular adicionará um controlador padrão do formulário que fará o prevent.default() para você. Sendo assim, você só precisa fazer:

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {LoginComponent} from './login.component';
import {HeaderLoginNfModule} from '../components/header-login-nf/header-login-nf.module';
import {InputTextModule} from 'primeng/primeng';
import {FooterModule} from '../components/footer/footer.module';
import { FormsModule } from '../../../node_modules/@angular/forms';

@NgModule({
  imports: [
    CommonModule,
    HeaderLoginNfModule,
    InputTextModule,
    FooterModule,
    FormsModule // importou o maldito aqui!
  ],
  declarations: [LoginComponent]
})
export class LoginModule { }

Não precisa fazer as outras alterações que compartilhei. Feche o Angular CLI e teste novamente.

Caro aluno, o problema que você passou é difícil mesmo de descobrir para quem esta começando com Angular. Como no curso eu sempre usei ReactiveForms esse problema não ocorria.

Aguardo seu retorno para saber se esta tudo OK! O que me confundiu um pouco no início é que achei que era problema no projeto do curso, mas é do seu projeto pessoal.

ESQUECI: você precisa alterar sua rota para:

const routes: Routes = [
  {path: '', component: LoginComponent },
  {path: 'home', loadChildren: './home/home.module#HomeModule'},
  {path: '**', component: NotFoundComponent}
];

Se não me engano, essa era a rota original que você queria ter, né?

Se quiser usar a primeira que você postou tá liberado também:

const routes: Routes = [
  {path: '', component: LoginComponent},
  {path: '', redirectTo: 'home', pathMatch: 'full'},
  {path: 'home', loadChildren: './home/home.module#HomeModule'},
  {path: '**', component: NotFoundComponent}
];

orraaa poderia estourar foguetes agora de felicidade \0/ Tragam um 'Mito' pra esse 'oscar'. XD Deu mais que certo. Só tenho a agradecer. Essa do form não sabia mas, vou anotar aqui. Fiquei impressionado. Não só por isso. Gosto de todas as suas aulas. São muito produtivas e aprende pra caramba. Gosto também do jeito que deixa transparecer que é você ali mesmo e não meio um boneco. As aulas se tornam diferentes e mais legais. "Teclado Maldito". XD Está de parabéns, assim o aluno se empolga mais a prestar atenção nas aulas sendo você mesmo. \0/ Uma última pergunta a quesito de ter certeza que não vou fazer errado quando modularizar as outras partes em lazy.

{path: '', component: LoginComponent },
  {path: 'home', loadChildren: './home/home.module#HomeModule'},
  {path: '**', component: NotFoundComponent}

Se eu tiver outro módulo Lazy pra carregar ficaria assim:

{path: '', component: LoginComponent },
  {path: 'home', loadChildren: './home/home.module#HomeModule'},
  {path: 'endereco2', loadChildren: '.... blah blah endereco2' },
  {path: '**', component: NotFoundComponent}

? pq aí os direcionamentos faria da mesma maneira nos meus menus de navegação quando fizer.

Obrigado pelo feedback!!! É por esse caminho mesmo. Só repetir a mesma estratégia.

Sucesso e bom estudo meu aluno!

Muito obrigado Flavio. Tudo de bom.