Failure of ngClass in Angular 7 due to the presence of multiple classes (spaces)

Many frontend frameworks have a practice of encapsulating their CSS styling by adding another class as a prefix.

For example, in Bootstrap: btn btn-primary where btn is the prefix.

If I were to conditionally apply this using [ngClass] in Angular, it would cause an issue:

<div [ngClass]="{'btn btn-primary': booleanVar, 'btn btn-danger': !booleanVar}"></div>

This problem can be solved easily by extracting the common class like this:

<div class="btn" [ngClass]="{'btn-primary': booleanVar, 'btn-danger': !booleanVar}"></div>
Voilà, now there are no spaces in the conditions and Angular approves.

Now let's apply this concept to Font Awesome icons, where prefixes can be found here.

Style       Prefix  Example 
Solid       fas     <i class="fas fa-igloo"></i>    
Regular     far     <i class="far fa-igloo"></i>    
Light       fal     <i class="fal fa-igloo"></i>    
Brands      fab     <i class="fab fa-font-awesome"></i> 

1st question: Can you use spaces in a conditional query? If so, how?

2nd question: (If the first question is not possible) How would you handle a situation where the prefix is not static (like in the case of Font Awesome)?

Answer №1

Upon further investigation, I have confirmed that using spaces is acceptable.

Therefore, the following code snippet should be functional:

<div [ngClass]="{'btn btn-primary': booleanVar, 'btn btn-danger': !booleanVar}></div>

Additionally, you have the option to utilize this format as well:

[ngClass]="booleanVar ? 'btn-primary': 'btn-danger'"

Answer №2

The process is completed on a class by class basis:

[ngClass]="{'btn': true, 'btn-primary': booleanVar, 'btn-danger': !booleanVar}"

Answer №3

Today I encountered a similar issue while working on an Angular 7 project. After some investigation, I identified the root of the problem. While ngClass allows for adding multiple space-separated classes, if the same class appears in multiple conditions, it may be removed if one of the later conditions is false. For instance:

<span [ngClass]="{
    'fas fa-book': val === 1, 
    'fas fa-eye': val === 2, 
    'far fa-star': val === 3 }">
</span>

If val === 3, there are no issues. However, if val === 1, the fas class will be removed. Similarly, if val === 2, the fas class will be momentarily removed and then added back again, functioning correctly.

In my observation, the classes are executed sequentially, with true conditions adding classes and false conditions removing all classes associated with that element. While I have not directly viewed Angular 7 code, my experiments support this theory.

For scenarios where the same class appears in multiple conditions, one solution is to rearrange the code so shared classes are located in different conditions, like this:

<span [ngClass]="{
    'fas': val === 1 || val === 2,
    'fa-book': val === 1, 
    'fa-eye': val === 2, 
    'far fa-star': val === 3 }">
</span>

For a demonstration of the issue, refer to this Plunkr: https://plnkr.co/edit/EouOaIfBkIR5Q29n?open=lib%2Fapp.ts&deferRun=1 (adjust the "val" value inside app.ts. The first span will not work for 1, but will work for 2 and 3)

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

attempting to display an element using jQuery that belongs to the identical class

I have multiple buttons with the class .modif, each with a different title attribute such as title="one". All these buttons are associated with boxes that share the class .box_slide. However, I am trying to display only the box that also has the additional ...

Is there a way to achieve element scrolling similar to scrollLeft within a scrollable container without using JavaScript

Looking for a CSS Solution: Is there a way to achieve element.scrollLeft functionality in CSS without using javascript? I want to pre-scroll a scrollable container. Situation Overview: I have a scrollable container that houses various items. Some instanc ...

Customizing the color of a select dropdown in Bootstrap using CSS styling

I am having difficulty changing the default blue color for Bootstrap select dropdowns. Despite trying :hover and :active selectors on both option and select, I have not been successful in making the desired changes. Could anyone provide insight regarding ...

Tips for creating a stylish scrollbar in a React Material-Table interface

Currently, I am utilizing the react material-table and looking to implement a more visually appealing scroll-bar instead of the default Pagination option. Although I have experimented with the react-custom-scroll package, it has not produced the desired ...

What is the reason behind the angular http client's inability to detect plain text responses?

When I make a call to httpClient.get, I notice in Fiddler that both the request and response headers have text/plain format. Request: Accept: application/json, text/plain, */* Response: Content-Type: text/plain; charset=utf-8 Even though I am returning a ...

Angular and Bootstrap4: The Perfect Duo for Modals

I need to display a Bootstrap4 modal window in Angular when a specific condition is met in my "bookTour" method without the need for a direct button click. How can I achieve this? Below is the code snippet: html <div class="modal" id="myModal" [ngClass ...

What is the best way to retrieve the border-color inline style using jQuery?

I have a HTML tag like this. <span id="createOrderFormId:accountNo" style="border-color: red;"><</span> To retrieve the style value for the border-color property, I tried using the following jQuery code: $( document ).ready(function() { ...

The arrow keys (up and down) are unresponsive when using mat-table in an Angular application

There seems to be an issue with my code. When I press the down arrow key for the first time, it goes to the next row as expected. However, when I press the down arrow key again, it does not function properly. (https://i.stack.imgur.com/4qznx.jpg) **HTML* ...

Methods for enlarging a sub-element without any impact on its encompassing parent element

I need the child class to not affect the overflow of the parent when I hover over it. My initial thought was to remove the line position: relative; from the parent, but this solution does not work properly when dealing with multiple nested positions. .p ...

Trouble with jQuery on click function, no actions triggered

I am having trouble with this jQuery function that is supposed to post the value of a variable to a PHP page and display it in the correct status class. I have included the necessary jQuery file, but for some reason, nothing is happening. Any assistance w ...

Ways to transfer the entered number to the input field located outside the angular modal

I'm currently working on creating a modal that includes a button and an input field for manually entering a number. Once the number is submitted, it should appear in the input field outside the modal and be available for various functions such as sett ...

The table __EFMigrationsHistory does not exist

Trying to navigate the world of .NET Core and facing some challenges. When I enter the following command in the VS Code terminal dotnet ef database update I encounter the following message: Build started... Build succeeded. info: Microsoft.EntityFramework ...

Connecting an Angular application to a URL hosted on localhost

I am currently working on an Angular project where one of the links needs to redirect to a different website. During development, this link points to a localhost URL like localhost:4210. However, due to security reasons in Angular, using such URLs is cons ...

New replacement for routerState.parent feature that has been deprecated in angular2

During my work with Angular 2 rc5, I encountered the following code snippet. this.router.routerState.parent(this.route).params.forEach((params: Params) => { url = params['url']; id = +params['id']; }); I had to resort to th ...

Tips for getting free jqgrid to display frozen column borders in the search toolbar

If the actions column has a caption of "Activity" or custom settings and is frozen, the free jqgrid will not display column borders for this column in the search toolbar. Vertical lines do not appear in the search toolbar: Is there a way to resolve this ...

Implement a JavaScript function that toggles the visibility of a div based on changes to an anchor tag

My objective is to have the lds-roller div only displayed when the text within the anchor tag with the ID of searchFor is equal to _. This change in text should occur with an HTTP response. <div class="lds-roller"><div></div><div> ...

The table on the page shifts position when viewed on different devices, sometimes not remaining between the header and footer

Here is a link to see how my page looks with the header, table, and footer: https://i.sstatic.net/U6tdO.png If you want to see how it looks when responsive (with smaller width), check out this link: https://i.sstatic.net/zsGkc.png I have encountered 2 ma ...

AngularJs - Customizable dynamic tabs that automatically adapt

Below is the HTML code snippet: <div> <ul data-ng-repeat ="tab in tabs"> <li data-ng-class="{active: tab.selected == 'true'}" message-key="Tab"> </li> </ul> </div> As shown ...

Arrange four divisions so that they are displayed in pairs on each row when the viewport width is smaller

I have a row of 4 div elements aligned horizontally from left to right. Each div takes up 25% of the screen width. I am looking for a solution to make them wrap when the user resizes the screen instead of overlapping each other. .MenuSett { margin-to ...

Ways to eliminate the extra space in a dropdown menu

Is there a way to eliminate padding on the "dropdown-menu" <ul> tag when the list is empty, so that no space is displayed in place of the padding? I want to avoid using .dropdown{padding: 0} because it will remove necessary padding when the list is ...