1

I'm using Bootstrap's navbar and I can get it to collapse successfully by using data-toggle and data-target on each li element.

This SO answer shows a way to do this without having to alter each li: https://stackoverflow.com/a/42401686/279516

This is my navbar with two of the li elements:

<div class="collapse navbar-collapse" id="navbarSupportedContent">
  <ul class="navbar-nav mr-auto">
    <li class="nav-item" data-toggle="collapse" data-target=".navbar-collapse.show">
      <a class="nav-link" href="#" routerLink="/servers">Servers</a>
    </li>
    <li class="nav-item" data-toggle="collapse" data-target=".navbar-collapse.show">
      <a class="nav-link" href="#" routerLink="/servers">Variables</a>
    </li>

I'm close to getting this done in my Angular 8 Typescript file:

export class AppComponent implements OnInit {
  ngOnInit(): void {
    const navbarItems = document.querySelectorAll('.navbar-nav>li');
    navbarItems.forEach(navbarItem => {
      navbarItem.addEventListener('click', () => {
        const navbar = document.querySelector('.navbar-collapse').collapse('hide');
      })
    });
  }
}

The issue is the last line:

Property collapse does not exist on type element.

First, what should I do to get this to work? Second, is there a better way?

I've tried casting navbar as different types of HTML elements, but that doesn't work either.

Bob Horn
  • 33,387
  • 34
  • 113
  • 219
  • Can you try this `(document.querySelector('.navbar-collapse')).collapse('hide');`? – Tnc Andrei Sep 10 '19 at 14:48
  • I just tried it. Same error. – Bob Horn Sep 10 '19 at 14:50
  • Have you considered using the Bootstrap widgets for Angular? The functionality you seek is provided all OOB: https://ng-bootstrap.github.io/#/components/collapse/examples – Canica Sep 10 '19 at 15:43
  • @jcruz I'm already using Bootstrap, and it's collapsing when hitting the hamburger menu icon. I'm just trying to enhance it by collapsing it when clicking an item within the navbar. – Bob Horn Sep 10 '19 at 16:12
  • @BobHorn the way you are doing it does not follow the MVC/MVVM pattern so its not clear that you are using ng-bootstrap. Anyway, it is best practice to use the pattern similar to the Jens answer. – Canica Sep 10 '19 at 17:24

2 Answers2

1

You can do it more the Angular way. Like this:

<button class="navbar-toggler" type="button" (click)="showMenu=!showMenu">
    <span class="navbar-toggler-icon"></span>
 </button>
 <div class="collapse navbar-collapse" [ngClass]="{'show':showMenu}">
     ...
 </div>
Jens Alenius
  • 1,931
  • 2
  • 16
  • 20
0

I was able to get it to work by removing 'show' from the class list, shown on the last line here.

(I'm still not sure if this is a good approach, but it's working.)

export class AppComponent implements OnInit {
  ngOnInit(): void {
    const navbarItems = document.querySelectorAll('.navbar-nav>li');
    navbarItems.forEach(navbarItem => {
      navbarItem.addEventListener('click', () => {
        const navbar = document.querySelector('.navbar-collapse');
        navbar.classList.remove('show');
      })
    });
  }
}
Bob Horn
  • 33,387
  • 34
  • 113
  • 219