Unusual occurrence in Angular 2: The root element's style properties are coming back as empty strings

Currently, I am exploring Angular2 and have reached a point where I want to implement dynamic style extension in Angular2 components. To clarify things further, here is some code:

Main.ts

import {bootstrap}    from 'angular2/platform/browser';
import {App} from './app'

bootstrap(App).then(error => console.log(error));

App.ts

import { Component } from 'angular2/core';
import { Button } from './button';

@Component({
    selector: 'app',
    template: `<button [style.background]="'green'">Hello World</button>`,
    directives: [Button]
})
export class App { }

Button.ts

import {Component, Input, ElementRef, Renderer} from "angular2/core";
import {BrowserDomAdapter} from "angular2/src/platform/browser/browser_adapter";

@Component({
    selector: 'button',
    templateUrl: '<span [style.color]="test"><ng-content></ng-content></span>',
    providers: [BrowserDomAdapter]
})
export class Button {
    test: string;

    constructor(private renderer:Renderer, private elementRef:ElementRef, dom: BrowserDomAdapter) {
        let styles = elementRef.nativeElement.style;
        console.log(styles);

        this.test = styles['background'] || 'red';
        console.log(this.test);
    }
}

Now, onto something that could be considered a unique behavior. Just to note, I am not very experienced with DOM manipulations, but I have been stuck on this issue for hours without finding a solution.

When running this app, the following output is displayed in the console:

  • CSSStyleDeclaration {...}
  • red*

*The styles['background'] shows an empty string

However, in the CSSStyleDeclaration, 'background' is set as "green", as expected since it is an inline style.

To verify, I also tested it in different browsers (Chrome and Firefox only) and checked the 'style'-Property on this website(It works fine here):

http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_style_get_elmnt

After all the testing, I was unable to find a suitable solution. Even using the BrowserDomAdapter did not work, as it utilized the same code to fetch the style properties.

Is this a bug within the Angular2 Framework? If so, has it been reported and are there any possible workarounds? If not, are there any alternatives or will there be changes in the future?

While this feature is not crucial, it would aid me in my work. I require this functionality because I am utilizing dynamically generated stylesheets, and users of my components should be able to override them using ngStyle and the '[style.property]' syntax of Angular2. Note that I prefer not to use the 'style'-Property of the Component-Decorator and simply override them for certain reasons.

Thank you for your assistance.

Answer №1

While digging into the code in firefox, I stumbled upon the solution to my problem. It finally became clear why this issue was occurring. The browser is actually displaying a version of the 'style' Property that is newer than the one present when my constructor is executed.

The style changes have not been applied yet, and I am currently unsure about where they will be applied.

Update: I figured it out now. Well, almost. Although I don't know the exact location where the style is going to be applied, it's not really necessary for me to achieve what I want. One important thing to note is that the constructor in Angular2 is too early to handle DOM manipulations. It's essential to utilize other lifecycle methods like 'ngOnInit' or leverage the 'host' Property of the Component decorator to achieve the desired behavior.

To further elaborate on the explanation above, here is a snippet of code from 'button.ts'. Make sure to refer to the question's files for context.

button.ts

import {Component, Input, ElementRef, Renderer, Inject, OnInit} from "angular2/core";
import {BrowserDomAdapter} from 'angular2/platform/browser';

@Component({
    selector: 'button',
    templateUrl: 'app/button.html',
    providers: [BrowserDomAdapter]
})
export class Button implements OnInit {
    get test() {
        let dom = this.dom
        let root = this.elementRef.nativeElement;

        return dom.getStyle(root, 'background-color') || 'red';
    }

    constructor(private renderer:Renderer, private elementRef:ElementRef, private dom: BrowserDomAdapter) {}

    ngOnInit() {
        let dom = this.dom
        let renderer = this.renderer;
        let root = this.elementRef.nativeElement;

        if(dom.hasStyle(root, 'background-color')) {
            let backgroundColor = dom.getStyle(root, 'background-color');

            renderer.setElementStyle(root, 'color', backgroundColor);
        }
    }
}

This serves as a resolution to my issue, confirming that it's not a bug but rather an undocumented feature. Hopefully, this information can assist others facing similar challenges.

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

Using TypeScript to separate namespaces

tsconfig.json: ... "module": "none" ... file1.ts: namespace Myns { type Mytype = number } file2.ts: namespace Myns { let x: Mytype ^^^^^^ Error - unable to locate declaration in file1.ts } Why am I encountering an error when trying to us ...

Displaying boolean and timestamp values within a react-table component is made easy with React Table, React, and Typescript

I'm facing an issue with printing the boolean and timestamp values retrieved from a specific API. Unfortunately, I have been unsuccessful in achieving this task. Any assistance on how to resolve this would be highly appreciated. Here is the column co ...

Improving DynamoDb Query Results with Type Hinting

In the following Typescript code, how can I specify which fields should be present in my Query Items Result? const request: DynamoDB.DocumentClient.QueryInput = { TableName: UnsubscriptionTokensRepository.TABLE_NAME, IndexName: 'TokenIndex&ap ...

The Angular Material date picker's keyboard input format is functional only in Chrome

I'm facing a challenge with the date picker component from Angular Material. When I try to manually type in a date like "2019.12.20" instead of selecting it, the input only works in Google Chrome. But when I tested it on Edge and Firefox, the date val ...

How to Send JS Type of 'Number' as an HTTP Response in Angular

I am currently developing an application using the MEAN stack (Mongo, Express, Angular, Node). In order to fetch the total number of entries in a collection, I am looking to create a GET route in Express that utilizes Mongo's countDocuments() method. ...

Utilizing TypeScript 2's Absolute Module Paths

The issue at hand: I am facing a challenge with relative module paths and have attempted to resolve it by configuring the baseUrl setting in my tsconfig.json file. Despite my efforts, I keep receiving an error indicating that the module cannot be found. I ...

As a quirk of TypeScript, it does not allow for returning a Tuple directly and instead interprets it as an Array

I need assistance with adding type-safe return to a general function created by a previous developer. Here is the current syntax: export function to(promise:Promise<any>) { return promise .then(data => [null, data]) .catch(err => [ ...

Angular is having trouble locating the module for my custom library

Trying to implement SSR in my angular application, but encountering an error when running npm run build:ssr. I've created my own library named @asfc/shared, which is bundled in the dist folder. ERROR in projects/asfc-web/src/environments/environment. ...

What are some ways to incorporate inline TypeScript Annotations into standard JavaScript code?

If you're using VSCode, there's a new feature that allows you to implement type checking for traditional JavaScript files. There are instances where I wish to specify the type of a variable or parameters in a method or function to enhance auto-co ...

Achieving successful npm caching in Azure DevOps for a .net core Angular project

I have a project for a client that involves building an Angular 10/.Net Core project, and it currently takes around 15 minutes. I've been experimenting with caching to optimize the process. Despite trying different configurations, when I add eq(variab ...

What is the significance of default parameters in a JavaScript IIFE within a TypeScript module?

If I were to create a basic TypeScript module called test, it would appear as follows: module test { export class MyTest { name = "hello"; } } The resulting JavaScript generates an IIFE structured like this: var test; (function (test) { ...

The error that has occurred is: `TypeError: The object on the right side of the 'instanceof' keyword is

Testing my function that verifies if a variable is an instance of a specific type and performs an action has been successful. I conduct the verification using the following code: myCheckingFunction = () => { if (target instanceof H.map.Marker) { ... ...

What is the best way to insert an HTML attribute into a dynamically generated build script within Angular?

After running the ng build --prod command, Angular creates 4 scripts. One of these is called main.js. I am wondering if there is a way to dynamically add an HTML attribute to this script tag in the index.html file once the build process is complete. I nee ...

Attention! npm has detected that package @angular/core@^6.0.3 is a required peer of [email protected], but it seems that it is not currently installed in your project. It is

I'm looking to create a circular progress bar in Ionic. I've tried installing npm install <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="82e3ece5f7eee3f0aff1f4e5aff0edf7ece6aff2f0ede5f0e7f1f1e0e3f0c2b3acb2acb5">[em ...

Typescript typings for higher order components in React

I am currently attempting to incorporate an existing react component (react-select) within a High Order Component (HoC) to implement conditional rendering logic. The challenge lies in ensuring that TypeScript can properly integrate the properties of both t ...

How to Track URL Modifications within an Iframe on an Angular Ionic Mobile Application

Issue I'm currently working on identifying modifications in the URL of an embedded <iframe /> within an Ionic (v5) app using Angular. Solution // ts file @ViewChild('myIframe') public iFrame; backButtonSubscription: Subscription; ...

Show details when clicked with various elements

I have a dilemma with my Angular version 7 project. In a div, I have placed 6 buttons in 2 columns and I want to show a description of one button only when it is clicked. Currently, the description for all buttons displays at once upon clicking any button. ...

I'm having trouble getting my nav-tab to function properly in Bootstrap 4 when used with Angular 4. Can

I have been attempting to utilize Bootstrap 4 tabs with Angular 4 with the expectation that it would resemble and function similar to this example enter link description here However, my page is displaying like this. https://i.sstatic.net/dymNH.png Here ...

Attention: WARNING regarding the NEXTAUTH_URL in the Development Console

While working on my Next.js web application with next-auth for authentication, I came across a warning message in the development console. The message is related to reloading the environment from the .env.local file and compiling certain modules within the ...

The confirm alert from Material UI is being obscured by the dialog

How can I ensure that a material ui dialog does not hide the alert behind it when confirming an action? Is there a way to adjust the z index of the alert so that it appears in front of the dialog? import Dialog from "@material-ui/core/Dialog"; i ...