Search code examples
angularexpressionangular2-directives

Angular 2 ngClass not evaluating my expression when checking against condition


I have an expression in Angular 2 called selectedState. The expression evaluates to one of five properties inside of const. Depending on which is clicked it changes the class name.

                    <button
                        class="button button--secondary"
                        [ngClass]="selectedState">
                        <div class="u-maxX u-centerX">
                            <span>Button</span>
                            </div>
                        </div>
                    </button>

"selectedState" will return whichever item is clicked; default, is-hovering, is-active, disabled, and loading.

e.g. If I click is-hovering it will return

                    `<button
                        class="button button--secondary is-hovering">
                        <div class="u-maxX u-centerX">
                            <span>Button</span>
                            </div>
                        </div>
                    </button>`

Now when I change the syntax like so.

                    <button
                        class="button button--primary"
                        [ngClass]="{selectedState: type === 'primary'}">
                        <div class="u-maxX u-centerX">
                            <span>Button</span>

                        </div>
                    </button>

Now "selectedState" evaluates to the string "selectedState" instead of being dynamic and changing like before. How can I keep the dynamic behavior while checking for type === 'primary'? I need to check for type because there are several types on the page. I need each type to ONLY affect one button otherwise it will affect all the buttons on the page.


Solution

  • You should keep as much logic out of your templates as possible, so either bind [ngClass]="someVariable" and mutate that variable by calling functions, or bind [ngClass]="someFunction()" and have that function return the appropriate class name based on some set of conditions.

    For example, have a button that calls the setIsHovering function, and another button that calls the setIsActive function etc., then define those functions:

    setIsActive() {
        this.selectedState = "isActive";
    }
    
    setIsHovering() {
        this.selectedState = "isHovering";
    }
    

    And define the ngClass as:

    [ngClass]="selectedState"
    

    Or, define a selectedState function:

    selectedState() {
        if(this.isHoveringStateVariable == true) {
             this.selectedState = "isHovering";
        } else if (this.isActiveStateVariable == true) {
              this.selectedState = "isActive";
        }
    }
    

    And define the ngClass as:

    [ngClass]="selectedState()"
    

    Obviously replace this.isHoveringStateVariable with whatever logic is appropriate for determining what the actual current state is.