Search code examples
angularangular-routingangular-router

angular router load 2 component view on same page . lazy load router outlet issue


I have a form which has 3 steps and the user needs to see one step at a time and if it is valid than move to next step and so on.

So trying with the router and lazy load component

initially page load automatically

http://localhost:8080/init/first

But when I click on next button from first component HTML page.

Desired behavior: only second component and it's HTML will be loaded on the page.

Actual behavior: second component HTML loaded and beneath that HTML first component HTML is also visible.

And now when we click on next button on second component all 3 component's HTML visible on the same page which is not the desired output.

Below is the related code.

init.module.ts

import { InitRoutes } from './init.routing';

import { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';
import { ThirdComponent } from './third/third.component';
import { SummaryComponent } from './summary/summary.component';

@NgModule({
    imports: [
        CommonModule,
        RouterModule.forChild(InitRoutes),
        FormsModule,
        ReactiveFormsModule,
    ],
    declarations: [
        FirstComponent,
        SecondComponent,
        ThirdComponent,
        SummaryComponent,
    ],
})

export class InitModule { }

init.routing.ts

import { Routes } from '@angular/router';

export const InitRoutes: Routes = [
    {
        path: '',
        children: [
            {
                path: 'first',
                component: FirstComponent,
                data: { step: 1 }
            },
            {
                path: 'second',
                component: SecondComponent,
                data: { step: 2 }
            },
            {
                path: 'third',
                component: ThirdComponent,
                data: { step: 3 }
            },
            {
                path: 'summary',
                component: SummaryComponent,
            },
            {
                path: '',
                redirectTo: 'first',
                pathMatch: 'full'
            },
            {
                path: '**',
                component: FirstComponent
            }
        ]
    }
];

app.routing.ts

export const AppRoutes: Routes = [
    {
        path: '',
        component: InitLayoutComponent,
        children: [
            {
                path: '',
                redirectTo: 'init',
                pathMatch: 'full'
            }, {
                path: 'init',
                loadChildren: './init/init.module#InitModule'
            }]
    }, ...]

init-layout.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'app-layout',
    templateUrl: './init-layout.component.html',
    styleUrls: ['./init-layout.component.less']
})
export class InitLayoutComponent { }

init-layout.component.html

<div >
    <figure>
      <img class="logo" src="assets/images/logo.png" alt="logo">
      <figcaption class="f-18 font__normal--semibold"> Initialization Wizard </figcaption>
    </figure>
    <div class="card">
            <!-- Nested view  -->
            <router-outlet></router-outlet>
        </div>
</div>

first.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { Router, Route, ActivatedRoute } from '@angular/router';

@Component({
    selector: 'app-first',
    templateUrl: './first.component.html',
})

export class FirstComponent implements OnInit {

    public firstForm: FormGroup;

    step: number;

    constructor(private fb: FormBuilder, private router: Router, private route: ActivatedRoute) {
        this.buildForm();
    }
    ngOnInit() {
        this.route.data.subscribe((data) => {
            this.step = data.step;
        });
    }
    next() {
        console.log('click on next ', this.step, this.route.outlet);
        //this.router.navigate(['/init/second']); this also dows not works
        this.router.navigate(['second'], { relativeTo: this.route.parent, skipLocationChange: true });

    }


    private buildForm() {
        this.firstForm = this.fb.group({
            licenseKey: [null, <any>Validators.required]
        });
    }
}

what can be the issue? I have also tried with outlet parameter but did not succeed

version details

"@angular/animations": "^4.0.0",
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.3.4",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",

Solution

  • solved the issue.

    actually, all component's respective HTML must have the correct form structure.

    one of my pages has reactive form but invalid syntax. that's why it was giving unexpected output