Search code examples
typescriptangular6angular-material-6mat-tab

mat-tab-nav-bar tabs not showing up


When using the mat-tab-nav-bar from Angular Material, the tabs aren't appearing on the Angular 6 SPA.

Here is the code:

forms.component.html:

<nav mat-tab-nav-bar>
  <a mat-tab-link
    *ngFor="let link of [navLinks]"
    [routerLink]="[link.path]"
    routerLinkActive #rla="routerLinkActive"
    [active]="rla.isActive">
    {{link}}
  </a>
</nav>
<router-outlet></router-outlet>

forms-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { NamesComponent } from './names/names.component';
import { FileNameListComponent } from './file-name-list/file-name-list.component';

const navLinks: Routes = [
    {path: 'app-names', component: NamesComponent},
    {path: 'app-file-name-list', component: FileNameListComponent},
    {path: '**', redirectTo: 'app-names'}
  ];

  @NgModule({
    imports: [RouterModule.forRoot(navLinks)],
    exports: [
      RouterModule
    ]
  })

export class FormsRoutingModule {

}

forms.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-forms',
  templateUrl: './forms.component.html',
  styleUrls: ['./forms.component.css']
})
export class FormsComponent  {}

app.module.ts

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

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MainNavComponent } from './main-nav/main-nav.component';
import { LayoutModule } from '@angular/cdk/layout';
import { MatToolbarModule, 
  MatButtonModule, 
  MatSidenavModule, 
  MatIconModule, 
  MatListModule, 
  MatTabsModule 
} from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsComponent } from './forms/forms.component';
import { RoutingModule } from './routing.module';
import { ReportsComponent } from './reports/reports.component';
import { NamesComponent } from './names/names.component';
import { FileNameListComponent } from './file-name-list/file-name-list.component';
import { FormsRoutingModule } from './forms-routing.module';

@NgModule({
  declarations: [
    AppComponent,
    MainNavComponent,
    FormsComponent,
    ReportsComponent,
    NamesComponent,
    FileNameListComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    LayoutModule,
    MatToolbarModule,
    MatButtonModule,
    MatSidenavModule,
    MatIconModule,
    MatListModule,
    MatTabsModule,
    BrowserAnimationsModule,
    RoutingModule,
    FormsRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

In forms.component.html, when I specify the navLinks individually as below the tabs do show up. However, when I click on the app-names tab and go to the component, the tabs disappear.

*ngFor="let link of ['app-names','app-file-name-list']

So there are two issues:

  1. I can't use navLinks in the *ngFor.
  2. When specifying the tab names individually, the tabs disappear after I click on one of them and go to the component.

Thanks for the help!


Solution

    1. navLinks in forms.component

    To be able to access navLinks in forms.component.html, you need to put them in forms.component.ts.

    I don'T see it there in your current component. Routes (in your route config) are one thing - links are another. Your template (html) can only access the html.

    1. Dissapearing navigation

    Your routing configuration is different from what you want. When you look at nav links -they're in your forms component. Then you click one - and you navigate away, to another component. If you want these other components to be child components, you need to adjust route config like that too:

    const navLinks: Routes = [
      {
        path: 'app-names',
        component: NamesComponent, 
        children: [
          { path: 'app-file-name-list', component: FileNameListComponent, },
          { path: '**', redirectTo: 'app-names' },
        ],
      }
    ];
    

    Now your components will render in that nested router-outlet - not in the main one of the app.