Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is ngClass calling function indefinitely?

Tags:

I am attempting to add a class based off of whether or not a value is present in storage, or set to a specific value. I am attempting to use [ngClass] for this. For some reason, my function to check the storage is getting called infinitely. What is causing this behavior and how can I stop it?

One example of the usage in my html file:

<div id="level2" class="cell middle" [ngClass]="{'locked': checkLevel(2)}">

checkLevel function:

checkLevel(level): any{
        console.log("checkLevel(" + level + ")");
        var result = this.storage.getLevel(level.toString());
        console.log(result);
        if (result == null || result['status'] == 'locked'){
            return true;
        } else {
            return false;
        }
    }

getLevel function:

getLevel(level:string):any{
        console.log("Inside getLevel.");
        this.storage.get('games' + level).then((val) => {
            console.log(val);
            return val;
        });
    }

Output to the console:

checkLevel(10)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(11)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(12)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(13)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(14)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined

And it just keeps doing that forever. Cycling through all of the places that I use the [ngClass]. The actual levels page is never displayed.

--CONTEXT UPDATE--

I am using this on a page that contains a slider with 3 slides. Each slide contains 9 divs or 'cells' that represent a single level. There are 27 levels and that will never change, so the levels are static elements on the page (not loaded dynamically). Each level (except the first) is initially locked. Completing a level will unlock the next one. Or, levels can be unlocked by using the in game currency. So I need to check the local storage and set the locked class if there is no data for the level, or if the level has a status of locked. If it is unlocked, do not apply the locked class.

I just need some way to dynamically change classes based off of the level data that I am returned.

like image 869
Tristan Avatar asked Apr 19 '18 01:04

Tristan


1 Answers

If you have a method in your binding, it will be called every time change detection runs.

If you need to update parent button by clicking on another parent button, try this:

Template:

<button (click)="updateLockClass()">Click to update</button>
<button type="button" [ngClass]="lockClass">Button with "lockClass</button>

App component:

export class AppComponent {
  lockClass = "";

  checkClass(num) {
    return num == 2;
  }

  updateLockClass() {
    this.lockClass = this.checkClass(2) ? "lockClass2" : "lockClass";
  }
}

If you need to update child button by updating parent value that gets parsed into child component, try this:

parent component:

<app-child [childMessage]="parentMessage"></app-child>
    <input [(ngModel)]="parentMessage">

child.component.html

<button type="button" [ngClass]="childClass">Child Button with "childClass"</button>

child.component.ts

import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./app.component.css"]
})
export class ChildComponent implements OnChanges {
  childClass = "";
  @Input() childMessage: string;

  checkClass(num) {
    return num == 2;
  }

  updateChildClass() {
    this.childClass = this.checkClass(2) ? "lockClass3" : "lockClass";
  }

  constructor() {
  }

  ngOnChanges(changes: SimpleChanges) {
    console.log('Change detected:', changes.childMessage);
    if (changes.childMessage.currentValue != "Change parent value!") {
      this.updateChildClass();
    }
  }
}

Link to codesandbox: https://codesandbox.io/s/1y4wnz423

like image 109
Arielle Nguyen Avatar answered Oct 11 '22 12:10

Arielle Nguyen