Angular Built-in Directives are not working(ngClass, ngStyle, ngIf)
Asked Answered
C

1

-1

I am following Template syntax section for the application of built-in attribute and structural directives from here https://v4.angular.io/guide/template-syntax#ngclass

currentClasses: {};
    setCurrentClasses() {
    // CSS classes: added/removed per current state of component properties
    this.currentClasses =  {
    'saveable': this.canSave,
    'modified': !this.isUnchanged,
    'special':  this.isSpecial
  };
}

I add currentClasses to my html as per Angular documentation above:

<div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>

On browser's console I am getting the following error:

Error: Template parse errors: Can't bind to 'ngclass' since it isn't a known property of 'div'.

I tried also ngStyle and ngIf but getting the same error code.

My app.module.ts includes Common Module as this was the suggested solution in some of the answers - but this has not helped me:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { AppComponent } from './app.component';
import { MaterialModule } from './material-module';
import { HighlightDirective } from './highlight.directive';

import { BrowserAnimationsModule } from '@angular/platform 
browser/animations';
import { PlatformModule } from '@angular/cdk/platform';
import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout';

// import { MediaService } from './Media.service';

@NgModule({
  declarations: [
    AppComponent,
    HighlightDirective
  ],
  imports: [
    CommonModule,
    BrowserModule,
    BrowserAnimationsModule,
    MaterialModule,
    PlatformModule  
  ],
  providers: [BreakpointObserver, MediaMatcher],
  bootstrap: [AppComponent]
})

export class AppModule { }

I could not make it a work by myself and also after following some other answers given to similar questions.

I am using Angular 4.4.6 and webpack to compile.

Thanks very much for any help.

Conditioner answered 18/11, 2017 at 19:58 Comment(4)
Thanks for your comment. I read it carefully but I can't find a way around it. How do I make ngclass a bindable property for html elements ?Conditioner
Bind to ngClass not to ngclass. The error says you are binding to ngclass, but it is actually ngClass with a capital CNaji
This is exactly how I add to the component's html: <div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>. The console log error message says can't bind to 'ngclass' making ngClass in lower case. I believe that's because how web pack compiles the bundle. @DummyConditioner
Then, some other component has ngclass in its template, webpack only bundles up your code, it is angular that throws the error. Look at the entire stack traceNaji
C
1

The problem was caused by webpack loader particularly the "html-loader". The html-loader loads all the HTML you write in Angular in lowercase.

Basically, my angular code would have ngClass directive in a component's html file but when webpack compiled the code and loaded the html by "html-loader", "ngClass" would become "ngclass" and I would receive an error "Error: Template parse errors: Can't bind to 'ngclass' since it isn't a known property of 'div'.".

I found the way around on another question posted on stackoverflow. Below is the link:

webpack html-loaders lowercase angular 2 built-in directives

The solution is simple, html-loader can have options set up. You will need to add inside options object the following setting: caseSensitive: true

Below is my html-loader setting in my webpack config file and now I can bind to ngClass directive successfully. Hope it helps others.

        {
            test: /\.(html)$/,
            exclude: "/node_modules/",
            use: [
                { 
                    loader: 'html-loader',
                    options: {
                        minimize: true,
                        caseSensitive: true,
                        removeComments: false,
                        collapseWhitespace: false
                      } 
                }
            ]
        },
Conditioner answered 3/12, 2017 at 6:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.