Angular ViewChild using a Directive as a selector results in a value of null

I have been working on a test component that includes an example of two directives, with one being used as an attribute directive. I am utilizing the ViewChild decorator to access these directives in the ngAfterViewInit handler. However, when I try to retrieve the ViewChild for each directive, it returns undefined. Oddly enough, when inspecting the page, the directives are clearly present in the DOM.

If you want to take a look at the issue, here is a StackBlitz example: https://stackblitz.com/edit/stackblitz-starters-f3g4sv?file=src%2Ftest.component.ts

Below is the code snippet for the test component:

import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  QueryList,
  ViewChild,
  ViewChildren,
  ViewEncapsulation,
} from '@angular/core';
import { CommonModule } from '@common';
import { TestContainerDirective } from './test-container.directive';
import { OtherContainerDirective } from './other-test-container.directive';

@Component({
  selector: 'app-test',
  standalone: true,
  imports: [CommonModule, OtherContainerDirective],
  templateUrl: './test.html',
  styleUrl: './test.scss',
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppTestComponent implements AfterViewInit {
  @ViewChild(TestContainerDirective)
  public _testContainerRef!: TestContainerDirective;

  @ViewChild(OtherContainerDirective)
  public _otherContainerRef!: OtherContainerDirective;

  @ViewChildren(TestContainerDirective)
  _testContainerChildren!: QueryList<TestContainerDirective>;

  constructor() {}

  public ngAfterViewInit(): void {
    console.log('_testContainerRef', this._testContainerRef);
    console.log('_otherContainerRef', this._testContainerRef);

    console.log('_testContainerChildren', this._testContainerChildren);

    setTimeout(() => {
      console.log('_testContainerRef', this._testContainerRef);
      console.log('_otherContainerRef', this._testContainerRef);
    }, 0);
  }
}

The template for this test component looks like this:

<p>This is the test component</p>
<span>
  Open the console and look for the references to the directives below
</span>

<p></p>

<div appTestContainer>test container</div>

<other-container>other container</other-container>

Lastly, let's not forget about the test directives themselves:

@Directive({
  standalone: true,
  selector: '[appTestContainer]',
})
export class TestContainerDirective {
  constructor(public viewContainer: ViewContainerRef) {}
}

@Directive({
  standalone: true,
  selector: 'other-container',
})
export class OtherContainerDirective {
  constructor(public viewContainer: ViewContainerRef) {}
}

It's strange that despite following the approach outlined in the documentation, I'm still encountering this issue. Any insights or assistance would be greatly appreciated!

Answer №1

Ensure you have imported the TestContainerDirective in your TestComponent.

@Component({
  ...
  imports: [CommonModule, TestContainerDirective, OtherContainerDirective],
  ...
})

Additionally, make sure you are referencing "_otherContainerRef" correctly as this._otherContainerRef instead of this._testContainerRef.

public ngAfterViewInit(): void {
  console.log('_testContainerRef', this._testContainerRef);
  console.log('_otherContainerRef', this._otherContainerRef);

  console.log('_testContainerChildren', this._testContainerChildren);

  setTimeout(() => {
    console.log('_testContainerRef', this._testContainerRef);
    console.log('_otherContainerRef', this._otherContainerRef);
  }, 0);
}

View the demo on StackBlitz

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

Encountering an error when setting up a React-TypeScript ContextAPI

I am currently attempting to understand and replicate the functionality of a specific package found at: https://github.com/AlexSegen/react-shopping-cart Working within a React-Typescript project, I have encountered challenges when creating the ProductCont ...

What is the best way to include a mat-paginator with mat-cards?

Just starting out with Angular and trying to implement pagination for mat-cards instead of just tables. I have a lot of code and want to display only 8-10 cards per page. How can I achieve this? Below is my HTML and TypeScript code. .html file <div cl ...

Passing a method from a component to a service in Angular 9

Recently, I've been working on some websocket code that involves sending a message to the server and receiving a reply. The current implementation is functional, but I'm looking to refactor it by encapsulating it within a service and then callin ...

How should one effectively manage the use of dynamic `.apply()` in TypeScript?

Exploring a particular code snippet, it defines an object with three methods, each requiring a different number of arguments. The code then dynamically calls one of these methods based on a variable's value using the apply() method along with an args ...

The 'append' property is not present in the 'Headers' type in Angular 2

import { HttpClient, HttpHeaders } from '@angular/common/http'; export class LoginService { let headers: HttpHeaders = new HttpHeaders(); headers = headers.set('Content-Type', 'application/json'); } I encounter ...

Guide to integrating a Jquery third-party plugin in Angular 7

Recently, I integrated jQuery and a third-party plugin called "stiffChart" into my Angular 7 project. After installing jQuery and the plugin in my project, I declared them in angular.json file as well. However, when trying to call a method from the plugin, ...

Refreshing the PrimeNg Organization Chart through code executionPrimeNg Organization Chart

Using the p-organizationChart to display hierarchy, I encounter an issue where dynamically added child nodes do not display the expand arrow until I select a Node. Therefore, I am seeking a way to programmatically refresh the org-chart. Any suggestions on ...

Strategies for managing customer projects that require personalized components

Customization Challenge In the process of developing an application, I aim to achieve a balance between standard implementation and customizable features for customers. The customization can extend to various aspects such as behavior, style, or templates ...

Duplicate items within an array were found when receiving Node.js response data in Angular

I'm facing an issue where duplicate elements are being displayed in an Angular table when receiving data from Node.js. The array sent by Node.js contains 2 elements, but somehow it appears as 4 elements in the Angular table. This discrepancy is puzzli ...

Invoke an ActionCreator within a different ActionCreator

Calling an ActionCreator from another file is proving to be a challenge... The products.ts file contains the ActionCreators and Reducers for Products... import { setStock } from './Store.ts'; //.... export const addProduct = (product: IProduct) ...

Navigating through React Native with TypeScript can be made easier by using the proper method to pass parameters to the NavigationDialog function

How can I effectively pass the parameters to the NavigationDialog function for flexible usage? I attempted to pass the parameters in my code, but it seems like there might be an issue with the isVisible parameter. import React, { useState } from 'rea ...

What is the best way to showcase the outcomes of arithmetic calculations on my calculator?

In the midst of creating a calculator, I have encountered some issues in getting it to display the correct result. Despite successfully storing the numbers clicked into separate variables, I am struggling with showing the accurate calculation outcome. l ...

When a ListView item is clicked, a label will display text with text wrapping specific to the selected item in the list

Within the listview items, there is a label that should expand when clicked. For example, initially it only shows one line of text. Upon clicking on the label, it should expand to show 10 lines of text. Current Issue: At present, when I click on the firs ...

Warning: The attribute 'EyeDropper' is not recognized within the context of 'Window & typeof globalThis'

Attempting to utilize "window.EyeDropper" in a project that combines vue2 and TypeScript. When writing the following code: console.log(window.EyeDropper); An error message is generated by my Vetur plugin: Property 'EyeDropper' does not exist on ...

``Why Ionic 3 Popover Sizes Should Adapt to Different Screen

Currently in my Ionic 3 project, I am utilizing a popover with a set height using the following code snippet: editOpty(rw){ let popover = this.editOptyPopup.create(EditOptyPopoverComponent, rw, { cssClass: 'edit-opty-popover'}); popover ...

Unable to pass a parameter through an Angular http.get request

I've encountered an issue where I am attempting to pass the page number and page size values to a web API, but for some reason, no parameters are being passed. I have thoroughly debugged the application in VS Code, and verified that the pagingModel ob ...

Tips for displaying HTML content from a JSON web template

Currently, I am working with a JSON web template that consists of nested elements. My goal is to render HTML based on the content of this JSON web template. I attempted using ngx-schema-form, however my JSON does not contain properties variables. I also t ...

Adding a value to an array in TypeScript

When trying to add values to an array in my code, I encountered an error stating that "number" is not a valid type for the array. someArray: Array <{ m: number, d: Date}> = []; this.someArray.push(500,new Date(2020,1,15)); ...

Struggling to destructure props when using getStaticProps in NextJS?

I have been working on an app using Next JS and typescript. My goal is to fetch data from an api using getStaticProps, and then destructure the returned props. Unfortunately, I am facing some issues with de-structuring the props. Below is my getStaticProp ...

Exploring the integration of an Angular 4 application with Visual Studio 2017 using dot net core. Techniques for accessing configuration keys from appsetting.json in a TypeScript

I'm currently working on an Angular 4 application using Visual Studio 2017 with .NET Core. I need to figure out how to access configuration keys from appsetting.json in my TypeScript file. I know how to do it in the startup.cs file, but I'm strug ...