0

I am trying to make a collapsable menu bar using angular and bootstrap. I have the following codes. I have taken help from the code under topic Responsive Navbar provided in this link https://ng-bootstrap.github.io/#/components/collapse/examples#navbar.

my abc.html

<nav class="navbar navbar-expand-lg navbar-dark">
    <button (click)="isCollapsed = !isCollapsed" class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
  
    <div [ngbCollapse]="isCollapsed" class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto">
        <li class="nav-item">
            <a class="nav-link" [routerLink]="'.'" (click)="isCollapsed = true" href="#"><i class="fa fa-home fa-lg"></i></a>
        </li>
        <li class="nav-item">
            <a class="nav-link" [routerLink]="'.'" (click)="isCollapsed = true" href="#">cli1</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" [routerLink]="'.'" (click)="isCollapsed = true" href="#">cli2</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" [routerLink]="'.'" (click)="isCollapsed = true" href="#">cli3</a>
        </li>
        <li class="nav-item pl-lg-3">
          <button *ngIf="!isAuthenticated" (click)="oktaAuth.loginRedirect()" class="btn btn-outline-primary">Login</button>
          <button *ngIf="isAuthenticated" (click)="oktaAuth.logout()" class="btn btn-outline-secondary">Logout</button>
        </li>
      </ul>
    </div>
  </nav>

my abc.ts

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

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

  constructor(public router:Router) { }
  isAuthenticated: boolean;
  public isCollapsed = true;
  ngOnInit(): void {
  }

}

my abc.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

import { abcRoutingModule } from './abc-routing.module';
import { abcComponent } from './abc.component';

@NgModule({
  declarations: [abcComponent],
  imports: [
    CommonModule,
    abcRoutingModule,
    NgbModule
  ]
})
export class abcModule { }

After compilation I am getting the following errors:

error NG8002: Can't bind to 'ngbCollapse' since it isn't a known property of 'div'.
    
    <div [ngbCollapse]="isCollapsed" class="collapse navbar-collapse" id="navbarSupportedContent">
An student
  • 392
  • 1
  • 6
  • 16
  • The only thing I can see different is that in their docs they also define thediv with an explicit identifier as #collapse="ngbCollapse" – SomeStudent Sep 28 '22 at 14:44
  • Thank you for the comment. After keeping the identifier also I am getting the same error. – An student Sep 28 '22 at 14:46
  • Can you make a stackblitz with your code so we can cross compare to what they have in their example, because at quick glance everything seems correct. Usually that error is because your module is missing an import, in your case your module isn't missing anything – SomeStudent Sep 28 '22 at 14:59
  • Perhaps this will help? https://stackoverflow.com/questions/52264749/getting-ngbcollapse-since-it-isnt-a-known-property-of-div-error-after-movi – Robin Webb Sep 28 '22 at 15:22
  • are you using the lastest ng-bootstrap? – Eliseo Sep 29 '22 at 07:56

1 Answers1

0

It's not an answer else a brief explain about the "explicit identifier".

To indicate Angular that our div is a ngCollapse, we need add [ngbCollapse]

To mannage a ngbCollapsed

  1. Using the method toogle

    <p>
      <button type="button" class="btn btn-outline-primary"
          (click)="collapse.toggle()" 
          [attr.aria-expanded]="!collapse.collapsed"
          aria-controls="collapseExample">
        Toggle
      </button>
    </p>
    <div [ngbCollapse] #collapse="ngbCollapse">
      <div class="card">
        <div class="card-body">
          You can collapse this card by clicking Toggle
        </div>
      </div>
    </div>
    
  2. Using a variable

    <button type="button" class="btn btn-outline-primary"
         (click)="isCollapsed=!isCollapsed"
         [attr.aria-expanded]="!isCollapsed" 
         aria-controls="collapseExample">
      Toggle
    </button>
    </p>
    <div [ngbCollapse]="isCollapsed" >
    <div class="card">
      <div class="card-body">
        You can collapse this card by clicking Toggle
      </div>
    </div>
    </div>
    

See that in both cases you include in the div [ngbCollapse]. This indicate to Angular that our "div" is more than an htmlElement (moreover, it's a ngbCollapse).

When you want to use a method of ngbCollapse you need indicate to Angular that the template reference variable (the #collapse) is ngbCollapse (you write #collapse="ngbCollapse" and can use collapse.toogle() and collapse.collapsed.

If you use a variable you needn't use a template reference variable and control all with the variable

a stackblitz

In the example mix a bit the two concepts (and use a bannana sintax -the [(ngbCollapsed)] uneccesary-). The bannana Syntax [(ngbCollapsed)] is used only to give value to the variable "isCollpased" when we make the collapse.toggle(), we can see clearer if split the bannana syntax in the way

<div #collapse="ngbCollapse" [ngbCollapse] 
                             (ngbCollapse)="isCollapsed=$event">
Eliseo
  • 50,109
  • 4
  • 29
  • 67