How to Retrieve Element's Boundaries in Angular 2 Component

I am working on a component that functions as a popover. Here is the structure of the component:

import {Component, Input, ViewChild} from 'angular2/core'

declare var $: any;

@Component({
  selector: 'popover',
  template: `
  <div id="temp" [ngStyle]="{'position':'absolute', 'z-index':'10000', 'top': y + 'px', left: x + 'px'}"
       [hidden]="hidden" #temp>
    <ng-content></ng-content>
  </div>
  `
})
export class Popover {

  @ViewChild("temp") temp;

  private hidden: boolean = true;
  private y: number = 0;
  private x: number = 0;

  show(target, shiftx = 0, shifty = 0){
    let position = $(target).offset();
    this.x = position.left + shiftx;
    this.y = position.top + shifty;
    this.hidden = false;

    console.log("#temp", this.temp.nativeElement.getBoundingClientRect()); //all 0s
    console.log("temp id", document.getElementById('temp').getBoundingClientRect()); //all 0s
  }

  hide(){
    this.hidden = true;
  }
}

In the show() function, I am trying to access the value of getBoundingClientRect(), but it returns all zeros for the properties. However, when I execute

document.getElementById("temp").getBoundingClientRect()
in Chrome's console, I get the actual values. Why is there a discrepancy and how can I retrieve the accurate values within my component?

Answer №1

My approach to solving the problem involved using the Renderer in Angular instead of relying on setTimeout or lifecycle hooks that could be triggered multiple times.

import { OnInit, Renderer2} from '@angular/core';

...

export class MyComponent implements  OnInit {

    constructor(private el: ElementRef, private render: Renderer2) {}

    ngOnInit() {
        this.render.listen('window', 'load', () => {
            const rect = this.el.nativeElement.getBoundingClientRect().top;
        })
    }

}

This technique might prove useful for someone facing a similar issue.

Answer №2

After the content was displayed, there seemed to be a delay in the DOM update, but using a setTimeout with a delay of 10 resolved the issue.

Answer №3

For handling content checking in Angular, I recommend using ngAfterContentChecked() as it has worked flawlessly for me every time.

import { AfterContentChecked } from '@angular/core';

export class ModelComponent implements AfterContentChecked {
   ngAfterContentChecked() {
        // Add your code here
    }
}

I trust this suggestion will be useful to you. 😊

Answer №4

When it comes to this scenario, the ngAfterContentChecked function is what you need. As explained earlier.

The ngAfterContentChecked hook method is the final step in the lifecycle before the ngOnDestroy kicks in. For more information on Lifecycle Hooks, check out the details here.

It's important to handle tasks with caution here, as they could potentially impact performance.

Timing

This function is called after ngAfterViewInit() and each subsequent ngAfterContentChecked().

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

Is there a way to make the parent elements invisible when there are no child elements present?

Take this scenario for instance: <ul *ngIf="hasAnyPermission(['A:READ', 'B:READ', ...])"> <li *ngIf="hayPermission('A:READ')"> a </li> <li *ngIf="hasPermission('B:RE ...

Can I include a different website within an Angular project?

I've recently completed an Angular project and now want to embed a page within another Angular page. Specifically, I'm looking to include www.yahoo.com in my Angular application. ...

Tips for effectively navigating search results with pagination

I am struggling to figure out how to conduct an effective search when using pagination. Excuse my poor English writing skills. This is what I have attempted: var app = angular.module('appTelDirectory', []); app.controller('directoryList& ...

Unfortunately, the utilization of an import statement outside a module is restricted when working with Electron

Is there a solution to the well-known problem of encountering the error message "Cannot use import statement outside a module" when working with an Electron-React-Typescript application? //const { app, BrowserWindow } = require('electron'); impor ...

When utilizing mergeMap() in conjunction with a subject, the takeWhile() condition set on the observable being merged is disregarded

I am currently exploring ways to halt an observable. After studying blesh's post on github at https://github.com/ReactiveX/rxjs/issues/1542, I believe I am making progress. However, when I apply a switchMap() from my pauser Subject to the takeWhile() ...

The ng-disabled directive appears to be malfunctioning

In my angular-based application, I have a controller that includes the following HTML code for implementing pagination. <li class="{{(first) ? 'disabled' : ''}}"> <a href="" ng-click="pageChange('first')" ng-disa ...

What is the best way to send data from a child component to a parent component in Angular 2?

I want to retrieve data from my child component, which contains a form in a popup. How can I pass all the details to the parent component? Here is the TypeScript file for my parent component: import { Component, OnInit } from '@angular/core' ...

The styles are not being rendered on the Angular application

I have successfully implemented a Modal service with working HTML/CSS (Check it out on StackBlitz) div.cover { align-items: center; background-color: rgba(0, 0, 0, 0.4); bottom: 0; display: flex; justify-content: center; left: 0; ...

The controller's AngularJS function seems to be unresponsive

Issue with AngularJs ng-click Event I'm attempting to utilize the GitHub Search-API. When a user clicks the button, my Controller should trigger a search query on GitHub. Here is my code: HTML: <head> <script src="js/AngularJS/angula ...

What causes TypeScript to narrow the type when a return statement is present, but not when it is absent?

I am facing an issue with this script: type Input = string function util(input: Input) { return input } function main(input: Input | null) { const isNull = input === null if (isNull) { return 'empty string' } inpu ...

Retrieve() displays solely the initial array within an object

I am facing an issue with my Redux/React project where I am calling an API to search for a specific ID based on the useParams value. I suspect the problem lies in my return statement return data.hero.find(hero => <Hero key={hero.id} hero={hero} /> ...

Conceal Tooltips with Materialize CSS

I'm trying to figure out how to hide the tooltip that appears when hovering over this element using Materialize CSS. <li><a class="btn-floating green" onclick="window.print();return false;"><i class="material-icons tooltipped" data-pos ...

When creating nested objects, the defineproperty function on the object prototype does not trigger

Exploring and experimenting to unravel the workings of this feature, but I find myself puzzled by this particular scenario. Object.defineProperty(Object.prototype, 'a', {set: function() {console.log("Set!");} }); Based on my understanding, when ...

Node.js client-sessions malfunction when not utilized as a primary callback

When utilizing express.Router, I'm attempting to create a middleware for a particular router in my application that will establish and handle a session. However, this approach fails if the client-sessions session is not invoked directly by Router().us ...

No data returned when fetching with server-side rendering (SSR) requested

Seeking suggestions on how to implement loading items via API and server-side rendering. My SSR is set up using Express and Babel. Below is the component in question: class MyApp extends Component { constructor(props) { super(props) th ...

What is the best way to conditionally wrap a useState variable in an if statement without losing its value when accessing it outside the if block in reactjs?

I am facing a coding challenge with my cards state variable in React using the useState hook. I tried adding my array data to it but ended up with an empty array. Placing the state inside an if statement resulted in undefined variables. I attempted various ...

Encountering an "Unsupported Media Type" error while attempting to generate an Hpalm defect through the rest api

I have been attempting to create a defect through the hpalm rest api, but I keep encountering a "415 Unsupported Media Type" error. Here's what I've done so far: var postOptions = { jar: cookies, accept: 'application/json', ...

Using vuex-class to interact with Vuex in non-Vue components

Is it possible to access Vuex outside of a Vue component using vuex-class? In a typical scenario, the process is quite straightforward: // some JS file import store from './../store'; // path to Vuex store store.commit('ux/mutationName&ap ...

An alternate solution for achieving synchronous behavior in form submit button click event handling without using the async: false option

Operating with a login form is essential, and our current practice includes utilizing an AJAX call to validate information before proceeding with the login submission. Here is the existing code snippet being employed: (function ($) { var errorMessageH ...

What is the most efficient way to implement OR conditions in JavaScript for shorter code

Hello there! I have a question about optimizing conditions in code. Is there a more elegant way to write the following conditions? state === 'su' || state === 'ja' || state === 'fa' I was thinking if it could be simplified ...