Search code examples
angulartypescriptroutesangular-materialangular-activatedroute

Routing in matdialog in Angular


I am trying to add routing to a Angular Material Mat Dialog in angular. But there is an problem occurring.

When I try to add the route URL manually from

https://localhost:3200

to

https://localhost:3200/login

or

https://localhost:3200/signin

it don't pop up

Tab Switching Problem

Also, There is another problem that when the dialog is opened for login and then if i tab switch to SignIn there is no change in URL

Navbar.component.ts ( Dialog Initializing Component )

import { Component, OnInit, Output, EventEmitter, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

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


  flag: boolean;
  currentDialog: MatDialogRef<any> = null;

  //Dialog init
  constructor(public dialog: MatDialog, private route: ActivatedRoute, private router: Router) {

   }

  openDialog(tabvalue: number) {

    console.log(tabvalue);
    this.currentDialog = this.dialog.open(DialogComponent, {
      data: {tabvalue},
    });

    this.currentDialog.afterClosed().subscribe(result => {
      console.log(`Dialog result: ${result}`);
      this.router.navigateByUrl('/');
    });
  }

  ngOnInit(): void {
  }

}

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

export class DialogComponent {
  tabs = ['Login', 'Sign in'];

  constructor(@Inject(MAT_DIALOG_DATA) public data: any) { }

  // tabvalue have only two values 0 -> tabs[0] -> Login and 1 -> tabs[1] -> SignIn
  selected = this.data.tabvalue
}

Navbar.component.html ( template for above code )

<mat-toolbar mat-toolbar [routerLink]="['/']">

    <button mat-icon-button (click)="flag = !flag ; value()">

        <mat-icon>menu</mat-icon>
    </button>
    <a class="a-menu">
        <h1 class="h1-menu">Notes</h1>
    </a>
    <span class="example-spacer"></span>
    <button mat-raised-button routerLink="/login"  routerLinkActive="active" (click)="openDialog(0)">Login</button>
    &nbsp;
    <button mat-raised-button routerLink="/signin" routerLinkActive="active"  (click)="openDialog(1)">Sign In</button>
</mat-toolbar>

<!--app-navbar (valueChange)='sb.toggleCustom($event)'></app-navbar-->
<!--this is nothing-->

<app-sidebar [flag]="flag"></app-sidebar>

Dialog.component.html ( template for dialog )

<mat-dialog-content class="mat-typography">


    <mat-tab-group [selectedIndex]="selected">
        <mat-tab *ngFor="let tab of tabs; let index = index" [label]="tab">
            <app-login *ngIf="tab == 'Login'"></app-login>
            <app-signin *ngIf="tab == 'Sign in'"></app-signin>
        </mat-tab>
        
    </mat-tab-group>


</mat-dialog-content>
<mat-dialog-actions align="end">
    <button mat-button mat-dialog-close>Cancel</button>
    <button mat-button [mat-dialog-close]="true" cdkFocusInitial>{{selected == 0 ? 'Login' : 'Sign In'}}</button>
</mat-dialog-actions>

app.module.ts

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

import {A11yModule} from '@angular/cdk/a11y';
import {ClipboardModule} from '@angular/cdk/clipboard';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {PortalModule} from '@angular/cdk/portal';
import {ScrollingModule} from '@angular/cdk/scrolling';
import {CdkStepperModule} from '@angular/cdk/stepper';
import {CdkTableModule} from '@angular/cdk/table';
import {CdkTreeModule} from '@angular/cdk/tree';
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatBadgeModule} from '@angular/material/badge';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import {MatButtonModule} from '@angular/material/button';
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {MatCardModule} from '@angular/material/card';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatChipsModule} from '@angular/material/chips';
import {MatStepperModule} from '@angular/material/stepper';
import {MatDatepickerModule} from '@angular/material/datepicker';
import {MatDialogModule} from '@angular/material/dialog';
import {MatDividerModule} from '@angular/material/divider';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatGridListModule} from '@angular/material/grid-list';
import {MatIconModule} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
import {MatListModule} from '@angular/material/list';
import {MatMenuModule} from '@angular/material/menu';
import {MatNativeDateModule, MatRippleModule} from '@angular/material/core';
import {MatPaginatorModule} from '@angular/material/paginator';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatRadioModule} from '@angular/material/radio';
import {MatSelectModule} from '@angular/material/select';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatSliderModule} from '@angular/material/slider';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatSortModule} from '@angular/material/sort';
import {MatTableModule} from '@angular/material/table';
import {MatTabsModule} from '@angular/material/tabs';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatTooltipModule} from '@angular/material/tooltip';
import { MatTreeModule } from '@angular/material/tree';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {MAT_FORM_FIELD_DEFAULT_OPTIONS} from '@angular/material/form-field';

import { Routes, RouterModule } from '@angular/router'; // CLI imports router
import { AppComponent } from './app.component';
import { NavbarComponent, DialogComponent } from './navbar/navbar.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { SigninComponent } from './signin/signin.component';
import { LoginComponent } from './login/login.component';
import { MainComponent } from './main/main.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';



const routes: Routes = [
  { path: '', component: NavbarComponent },
  { path: 'login', component: NavbarComponent },
  { path: 'signin', component: NavbarComponent },
  { path: '**', component: PageNotFoundComponent },
]; // sets up routes constant where you define your routes

@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    SidebarComponent,
    DialogComponent,
    SigninComponent,
    LoginComponent,
    MainComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    A11yModule,
    ClipboardModule,
    CdkStepperModule,
    CdkTableModule,
    CdkTreeModule,
    DragDropModule,
    MatAutocompleteModule,
    MatBadgeModule,
    MatBottomSheetModule,
    MatButtonModule,
    MatButtonToggleModule,
    MatCardModule,
    MatCheckboxModule,
    MatChipsModule,
    MatStepperModule,
    MatDatepickerModule,
    MatDialogModule,
    MatDividerModule,
    MatExpansionModule,
    MatGridListModule,
    MatIconModule,
    MatInputModule,
    MatListModule,
    MatMenuModule,
    MatNativeDateModule,
    MatPaginatorModule,
    MatProgressBarModule,
    MatProgressSpinnerModule,
    MatRadioModule,
    MatRippleModule,
    MatSelectModule,
    MatSidenavModule,
    MatSliderModule,
    MatSlideToggleModule,
    MatSnackBarModule,
    MatSortModule,
    MatTableModule,
    MatTabsModule,
    MatToolbarModule,
    MatTooltipModule,
    MatTreeModule,
    PortalModule,
    ScrollingModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule.forRoot(routes)


  ],
  exports: [RouterModule],
  providers: [
    { provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'fill' } },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Default View

Default View

On Click Login

Dialog Box Opened for Login

Manually Typing URL

Manually Typing https://localhost:3200/login

Output (without Dialog Box pop Up But URL changed)

Normal View No change


Solution

  • You need to import and declare the dialog component in "declarations" section. Then add the property "entryComponents" with the dialog component in "app.module.ts" file.

    import { YourDialog} from './modules/YourDialog.component';
    
    @NgModule({
      declarations: [...., YourDialog], 
      entryComponents: [YourDialog,]
    })