Angular tutorial: Accessing individual HTML elements within the *ngFor loop

I am facing an issue trying to access the "box-message" class using "document.querySelectorAll('.box-message')" within a tree structure where the "*ngFor" directive is utilized.

After making an "http rest" request, the *ngFor directive finishes constructing the components and then I attempt to retrieve the "box-message" class using "document.querySelectorAll('.box-message')".

However, it seems like there is not enough time for the components to be fully built, resulting in the inability to fetch the "box-message" class.

I have attempted using AfterViewInit without success. Any suggestions on how to resolve this issue?

HTML

    <ul class="ul-ads">
      <li class="li-ads" *ngFor="let ads of ads">
        <div class="box-message">{{ads.message}}</div>
      </li>
    </ul>

SCRIPT

        export class AdsComponent implements OnInit {


          ads!: Ads[];



          public getAds(): Observable<any> {

            return this.http.get<any>(`http://localhost:8080/apis/data/ads`,
              {observe: 'response'});

          }


          ngOnInit(): void {


            this.getAds().subscribe({

              next: data => {

                this.ads = responseData.body.content;

                const boxMessage = document.querySelectorAll('.box-message');
                console.log(boxMessage) // NodeList[]

              }


            });


          }


        }

https://i.sstatic.net/2DxME.png

Answer №1

If you want to achieve this, you can make use of the ViewChildren feature.

Simply add a reference for each box message in your template:

<ul class="ad-ul"&qt;
  <li class="ad-li" *ngFor="let ad of ads">
     <div #messageBox class="message-box">{{ ad.message }}</div>
  </li>
</ul>

In your component, create a property to store the view children and subscribe to the changes observable:

@ViewChildren('messageBox')
messageBoxes: QueryList<ElementRef>;

ngAfterViewInit(): void {
  this.messageBoxes.changes.subscribe(() => {
    // Your custom logic here
  });
}

Your code will be executed whenever there is a change in the view children, right after they are rendered.

No need for setTimeout to artificially delay the process.

Hope this guidance proves useful to you.

Answer №2

To ensure proper Angular repaint, it is recommended to use a setTimeout function without specifying milliseconds.

...
next: data => {
    this.ads = responseData.body.content;
    setTimeout(()=>{
       const boxMessage = document.querySelectorAll('.box-message');
       console.log(boxMessage) // NodeList[]
       console.log(this.ads.message) // to print data 
    })
  }

Keep in mind that Angular executes the instructions inside subscribe first before repainting, which may result in elements not being retrieved.

It is advisable to avoid using old JavaScript methods like document.getElementBy in Angular. You can utilize ViewChildren with template reference variables instead.

   <ul class="ul-ads">
      <li class="li-ads" *ngFor="let ads of ads">
        <!--see the #item-->
        <div #item class="box-message"& gt;{{ads.message}}</div>
      </li>
   </ul>

This way, you can access all elements in a QueryList.

@ViewChildren('item') items!:QueryList<ElementRef>

Note that the nativeElement property of an ElementRef represents the html tag element.

A Query List allows for conversion to Array, reordering, accessing the first and last elements, subscribing to changes, etc.

ngAfterViewInit()
{
     this.items.changes.subscribe(_=>{
         console.log(this.items.first.nativeElement)
         console.log(this.items.last.nativeElement)
         //the third element
         const htmlElement=this.items.find((_,index)=>index==2)?.nativeElement
         ...

     })
}

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

Split the text using the newline character (' ') and not the double newline character (' ')

Looking to create a filter that separates all \n and combines them back as \n\n. Is it possible to only target the single \n without affecting the double \n\n? Currently, the issue arises when the input field loses focus, caus ...

Tips for changing date format within Ajax javascript code

I am working with a JavaScript AJAX code: success:function(res){ var _html=''; var json_data=$.parseJSON(res.posts); $.each(json_data,function (index,data) { _html+='<span class=&apo ...

When using the hasMany/belongsTo relationship in VuexORM, the result may sometimes be

I have carefully followed the documentation and set up 2 models, Author and Book. The relationship between them is such that Author has many Books and Book belongs to an Author. However, despite having the author_id field in the books table, the associatio ...

Error message in Angular2 beta 11: "Cannot access property zone from undefined"

I've been attempting to integrate browser-sync into my gulp pipeline for development purposes, but despite following the setup steps in my gulpfile, I can't seem to get the automatic reload function to work. When I run gulp start, a browser tab o ...

Utilizing webpack for server-side development

I'm currently in the process of creating a node back-end service using express and I was thinking about incorporating webpack to bundle everything into a single file (although I'm not sure if this approach is correct as I'm still learning). ...

Retrieving saved data from LocalStorage upon page reload

<div ng-repeat="section in filterSections"> <h4>{{ section.title }}</h4> <div class="checkbox" ng-click="loaderStart()" ng-if="section.control == 'checkbox'" ng-repeat="option in section.options"> <label ...

Guide on creating a readUInt16BE function in a Node.js environment

Looking to implement the readUint16BE function in node.js, here's how it is declared: buf.readUInt16BE(offset, [noAssert]) Documentation: http://nodejs.org/api/buffer.html#buffer_buf_readuint16be_offset_noassert This function reads an unsigned 1 ...

I recently created an application using Vue and I'm exploring options for storing information to use later. Would using js-cookie be a viable solution for this?

After experimenting with Vuex to store user-selected information in my app, I found that the data was lost upon page reload. Switching to Cookies and using js-cookie solved this issue seamlessly. It makes me wonder if there is a downside to relying on cook ...

Building a personalized django widget to enhance functionality on other websites

Currently, I am in the process of developing a new website that includes user statistics. My goal is to create a widget that can be embedded on other websites using JavaScript to pull data from my server and display the statistics for a specific user. Howe ...

Only display PHP page content if accessed through an AJAX request, not through directly typing the URL into the address bar

Is there a way to verify if a PHP page has been accessed via an Ajax request? I'm working on a page that displays a form for updating some database data (update.php), but I only want it to be accessible if it is called by a specific page named "change ...

Is there a way to incorporate an icon into the heading of an accordion-group in ngx-bootstrap?

Is it possible to include an icon in the heading of an accordion-group using ngx-bootstrap? For instance: <accordion-group heading="<i class='fa fa-users'></i> Users"> The content goes right in the template. </accordion ...

Struggling to create a regular expression for a particular scenario

I'm dealing with nodes and currently faced with the task of applying a UNIX-like grep command to filter out specific content from an HTTP GET response. Below is the raw text received as the body variable: <?xml version="1.0" encoding="UTF-8" stand ...

Ways to determine the presence of a value in an array

Here is an example array: [ {practitioner: "place_1509136116761", H0709: false, H0911: false, H1113: false, H1315: false}, {practitioner: "place_1509136116772", H0709: true, H0911: false, H1113: true, H1315: false}, {practitioner: "place_15091361166 ...

Begin the Angular 4 project by loading it with RequireJS

I am currently in the process of constructing an Angular4 application using the ng command. Successfully, I can build and execute it with ng serve. Now, my aim is to incorporate RequireJS so that the Angular4 application can load and run smoothly. Despit ...

What is the best way to prioritize items on a list in JavaScript?

Looking to organize your to-do list items by priority? In this task list, users can enter an item, select a priority level, and add it to the list. Here is an example HTML form: <input id="task" type="text"/> <select id="priority"> <o ...

Function parameter accepting an anonymous value object

While working with prisma nexus and examining the prismaObjectType, I came across something unusual. A simple example of this is as follows: In a basic function, demo(p), the parameter p should be an object. function demo(p) { console.log(p); con ...

What is the process of transforming async/await code into synchronous code in JavaScript?

Blocking the event loop is generally considered bad practice due to its consequences. However, even the native fs module includes some synchronous functions for specific purposes, such as CLIs using fs.readFileSync. I am interested in converting the follo ...

Ways to show dynamic text according to slider adjustments

I am struggling with adding an if condition to my form that includes a horizontal slider. My goal is to display text based on the position of the slider. Can someone offer some guidance on this, please? Here's my HTML code snippet: <form method=" ...

How can you effectively test outgoing parameters in Angular?

I've been attempting to test a method from my service, but I'm encountering issues with the testrequest object not containing any parameters. Specifically, when trying to log 'username' and 'password', only 'null' va ...

Collaboratively accessing a shared constant in two separate JavaScript files

I am diving into the world of JavaScript and Node.js. I am currently experimenting with Puppeteer to extract the text value of a tag and store it in a constant variable. However, I am encountering difficulties when trying to integrate this value into my ...