Issue with accessing another component's HTML anchor (ngbNav)

I am facing an issue with navigation in my Angular application. I have two components and I want to navigate from the first component to the second, specifically to a particular pills tab, but it is not working as expected.

Initially, this is what gets displayed:

<!-- Error Modal -->
<div id="errorModal" class="modal modal-show" *ngIf="showModal">
  <div class="modal-content">
    <div class="modal-header">
      <h5 class="modal-title">Access Denied</h5>
    </div>
    <div class="modal-body">
      <p>{{ modalErrorMessage }}</p>
      <div class="mt-4 button-container">
        <button class="btn btn-lg btn-primary" (click)="navigateToMyAccount(); $event.preventDefault()">Go Back</button>
      </div>
    </div>
  </div>
</div>

Upon clicking on the button triggering the navigateToMyAccount() function, we execute the following code for navigation:

navigateToMyAccount(): void {
    this.router.navigate(['/my-account'], { queryParams: { tab: 'subscription' } });
}

In the second component, where we want to navigate, I utilize the following logic:

export class MyAccountComponent implements OnInit {
...
@ViewChild('nav', { static: true }) nav!: NgbNav;
async ngOnInit(): Promise<void> {
    this.route.queryParams.subscribe(params => {
      if (params['tab'] === 'subscription') {
        this.gotoSubscriptionTab();
      }
    });
...

  public gotoSubscriptionTab() {
    console.log('gotoSubscriptionTab called');
    if (this.nav) {
      console.log('nav is defined', this.nav);
      this.nav.select(2);
    } else {
      console.error('nav is not defined');
    }
  }

In the template of the second component, the navigation element looks like this:

<ul ngbNav class="nav-pills dark-nav-pills mb-3" #nav="ngbNav">
...

<li id="account" [ngbNavItem]="1">
...
<li id="subscription" [ngbNavItem]="2">

Despite various attempts, the navigation still fails with the error message:

nav is not defined

appearing in the browser's console. How can I ensure that the navigation works correctly from the first component to the specified ngbNavItem in the second component? I initially suspected a lifecycle problem, but even implementing AfterViewInit did not resolve the issue...

Thank you for your help!

Answer №1

There is something puzzling happening that I am trying to unravel. It seems like the key might lie in how Angular manages its lifecycle. Surprisingly, the solution below works, although it may not be the most elegant:

ngAfterViewInit(): void {
  const interval = setInterval(() => {
    if (this.nav) {
      clearInterval(interval);
      this.route.queryParams.subscribe(params => {
        if (params['tab'] === 'subscription') {
          this.gotoSubscriptionTab();
        }
      });
    }
  }, 500); // Check every 500ms

  this.cdr.detectChanges();
}

Essentially, we are waiting for the nav element to become available in the DOM. One would expect ngAfterViewInit to handle such situations automatically, but unfortunately, it falls short in this case. Interestingly, running this at ngOnInit could also be a viable option since ngAfterViewInit does not seem to make a difference here.

Answer №2

It looks like your code is valid, but it appears that the ngbNav element may be nested within a container with either *ngIf or *ngFor. According to the documentation:

When you set static: true, Angular expects the queried element to always be present and not conditionally rendered. This ensures that the query result is available earlier, during the ngOnInit lifecycle method.

To address this issue, remove { static: true } and move your code inside the ngAfterViewInit hook.

@ViewChild('nav') nav!: NgbNav;

ngAfterViewInit(): void {
  //
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method in XState to trigger an event with the parameters send('EVENT_NAME', {to: 'a value from the context'})?

I want to send an event to a different spawned state machine using its ID, which I have stored as a string in a variable within the context. This state machine is neither the parent nor child. For example: context.sendTo = 'B_id' How can I use ...

What is the process of transforming a jQuery element into a TypeScript instance?

In TypeScript, I am working with an object called DataTable that contains multiple methods, one of which is 'refresh' To display this DataTable on the page, it is structured as follows <table class='DataTable'>...</table> ...

Errors with optional chaining operator (?.) in node_modules directory when using Node, Typescript, and tslint

My node script works perfectly with node versions up to 17: $ nvm use 17 Now using node v17.9.1 (npm v8.11.0) $ cd src $ npx tsc $ npx node parser.js $ cd .. However, starting from node version 18, it throws an error related to the optional chaining opera ...

How is it that the chosen attribute functions for every ng-container?

I have 2 ng-containers. When I am in one view, I want "My Appointments" selected in the options dropdown when navigating to that view. In the other view, I want "Active" selected in the options dropdown. Here is my html code: <div class="wrapper w ...

Identifying actions on components that are dynamically generated

Below is an example of a dynamically created component in Angular 4 that I am currently working on. import { Compiler, Component, Injector, VERSION, ViewChild, NgModule, NgModuleRef, ViewContainerRef } from '@angular/core'; @Component( ...

Count duplicated values in an array of objects using JavaScript ES6

I am working on creating a filter for my list of products to count all producers and display them as follows: Apple (3) I have managed to eliminate duplicates from the array: ["Apple", "Apple", "Apple"] using this helpful link: Get all non-unique values ...

How can I ensure that only the most recent value is sent in an RxJS Subject, clearing out any previous

In my Angular application, I have a grid with buttons in each row that open respective popups when clicked. To handle this functionality, I created a service with a property called popupEventSubject$, which is a BehaviourSubject. The problem I am encounte ...

What is the method in AngularJS 2 to control the communication of input/output properties between a parent and child component when the child is called using route-config

Currently, I am developing an application with AngularJS 2. In this project, I have created a parent component called "LayoutComponent" and multiple child components are invoked using @RouteConfig, as shown below: @RouteConfig([ { path: '/dashboard&a ...

Issues persist with the implementation of async in Angular2+

In my Angular2+ component, I created a function that outputs the results before actually running the function. This causes the desired output to appear later than expected. The function sends a variable parameter with an HTTP request to a NodeJS backend an ...

Retrieving information from a data file by implementing a GraphQL Apollo Server within a NextJS application route

Currently working with Next.js 14 (app route), React, and the GraphQL Apollo framework. I have a JSON file containing data saved locally that I'd like to display using the server API. How can I make this happen? Below is the JSON structure I need to r ...

The licensed Angular Google Map component is failing to display the map

I've been experimenting with the new Google Map component developed by the Angular Team (from the package @angular/google-maps) with the help of this insightful tutorial. Unfortunately, I'm facing an issue where the map isn't being displaye ...

An issue with Angular 7 and Form Arrays is causing a button within a form group to remain disabled even when the associated form group is not valid, resulting in an undefined

I am working on a form array that generates form controls for each row along with a button. The challenge I'm facing is to disable the button associated with a row if the form group related to that row in the form array is not valid. Here is the but ...

Converting Next.js with MongoDB to TypeScript

I recently set up a next.js application using the mongodb template: npx create-next-app --e with-mongodb my-app Additionally, I included TypeScript in my project. Now, I am faced with the task of converting /lib/mongodb.js to TypeScript. Currently, the f ...

Link JSON object array to a form by utilizing ngModel in Angular2

My current challenge involves creating a form for a "question" object, which consists of an array of strings for answers. I am struggling to bind these answers to the question model. An initial implementation might look like this: import { Component } f ...

The error encountered is: "todos.map is not a function."

I am currently developing a task management application using React, Redux, and TypeScript with hooks. While the code compiles without any errors, I am facing an issue where the app fails to run in the browser. The specific error message states: TypeEr ...

Dealing with User Registration and Form Data in MERN Stack: Challenges with FormData Usage and Verification

I've encountered an issue while working on a MERN stack application where I'm struggling to register a new user. The frontend form collects user data such as username, password, confirmPassword, salary, roles, and email, and sends it to the backe ...

No slides are available for display, resulting in the ngx-owl-carousel console message indicating that the carousel will not be re-rendered

I've been attempting to integrate ngx-owl-carousel-o into my Angular 11 application, but I keep encountering the following message in my console: There are no slides to show. As a result, the carousel will not be re-rendered. Unfortunately, nothing ...

Exploring the benefits of leveraging TypeScript with AWS NodeJS for improved stacktrace visibility over traditional JavaScript

I'm contemplating the idea of transitioning my existing JavaScript codebase to incorporate TypeScript in NodeJS. One aspect that I am concerned about is being able to view the stack trace in AWS CloudWatch (request log) in case an error occurs during ...

Error message: Unable to destructure the 'q' property from 'req.query' due to its undefined value

I encountered a problem while working on a console project and attempting to create a handler for the GET method in Next.js 14: TypeError: Cannot destructure property 'q' of 'req.query' as it is undefined. Below is the code snippet fro ...

Duplicated RxJs in Angular 5 with Webpack 4 and Rxjs 5 DllPlugin - a common issue plaguing

My current configuration includes: "webpack": "4.12.0", "rxjs": "5.5.9", "@angular" : "5.2.11" and I am bundling libraries with the DDL Plugin. { entry: {"rxjs_5_5_9": [ "rxjs ], "angular_5_2_11": [ "@angular/common", ...