0

When I use the following code to switch the class everything works fine

<p [ngClass]="idPresent ? 'alert alert-success' : 'alert alert-danger'">
  Working
</p>

On changing the value of IdPresent in the component, I can see the appropriate class being applied,

but when I use an object in the component for the same purpose it only works if idPresent is false. When I set the idPresent to true, the following code does not apply the appropriate class.

<p [ngClass]="idValueClass">
   Not working
</p>
public idPresent = false;
 
public idValueClass = {
  "alert alert-success" : this.idPresent,
  "alert alert-danger"  : !this.idPresent
};

Can someone help me figure out what am I doing wrong?

Update:

I am changing the value of idPresent after receiving response from REST API call

 ngOnInit(): void {
 this.http.get('http://localhost:8083/v1/uniqueid', {
  headers: {'Authorization':'Basic dXNlcjpwYXNzd29yZA=='}
 })
 .subscribe(response => {
    if(response) {
      console.log(response)
       this.serverId = response;
       this.idPresent = true;
    } else {
       this.idPresent = false;
    }
    console.log("idPresent : " + this.idPresent)
 })

}

After receiving response from server, I can see updated value in console.

1
  • If you're not using signal, remember inside subscribe function give the new value not only to this.idPresent else to idValueClass Commented Nov 16, 2023 at 8:00

3 Answers 3

3

To complementary @Yong Shun, in Angular 16 and 17 we can use signal

We can define:

  public idPresent = signal(false);

  public idValueClass = computed(() => ({
    alert: true,
    'alert-success': this.idPresent(),
    'alert-danger': !this.idPresent(),
  }));

  onClick() {
    this.idPresent.update(value => !value);
  }

Be carefull, the .html we need reemplace idPresent by idPresent() and idValueClass by idValueClass()

  <p [ngClass]="idValueClass()">
    Not working
  </p>
  Current idPresent: {{ idPresent() }}

A stackblitz full stolen from the Yong Shun stackblitz.

NOTE: See that in the stackblitz I use changeDetection:ChangeDetectionStrategy.OnPush, but, when a signal is update, Angular update the entire view

Sign up to request clarification or add additional context in comments.

2 Comments

I tried using signal but when making the suggested changes in html to replace idValueClass by idValueClass(), I get following error: error TS2349: This expression is not callable. Type '{ alert: boolean; "alert-success": WritableSignal<boolean>; "alert-danger": boolean; }' has no call signatures.
@Bagira, check the stackblitz in my answer, you need define: idValueClass = computed(() => ({...})
1

I believe that you mentioned the issue in which the "alert" class is removed.

From the documentation,

Object - keys are CSS classes that get added when the expression given in the value evaluates to a truthy value, otherwise they are removed.

This results that the last "alert" was false and will be removed from the class.

Modify the idValueClass as below:

public idValueClass = {
  alert: true,
  'alert-success': this.idPresent,
  'alert-danger': !this.idPresent,
};

Demo @ StackBlitz


Updated

As raised by @Eliseo, if you have a button or logic to update the idPresent, the idValueClass will not automatically reflect the latest value.

You need a trigger/change event to overwrite the idValueClass.

<button class="btn btn-primary" (click)="onClick()">Update</button>
onClick() {
  this.idPresent = !this.idPresent;
  this.idValueClass = {
    alert: true,
    'alert-success': this.idPresent,
    'alert-danger': !this.idPresent,
  };
}

Or implement a getter for idValueClass (However it is not a good practice, Refer: Getter and setter in templates is a bad idea)

6 Comments

See that the "idValueClass" object not change when you change the "this.idPresent"
Hi @Eliseo, sharp eyes! That will be another issue as the change of idPresent will not update idValueClass. Unless you need to overwrite the idValueClass when idPresent is updated.
From Angular 16, we can also use signal. NOTE: Personally I don't like so much, but I feel that we need getting use to use
@YongShun I updated question to show how I am updating the value. Do you see anything wrong there.
Hi @Bagira, the update you mention that updating the idPresent doesn't reflect to idValueClass. As similar what I write for the updated part. As you first declare the idValueClass variable and initialize the value with idPresent as value but not reference type. This will not auto update the idValueClass. Either you need to overwrite/re-assign the idValueClass or use the signal as @Eliseo's answer.
|
0

i ever this problem before, i ever any key name class can be hidden like "success", "alert", "warning" etc with same case before. i try to make it single name class (alert-success") , not mutiple class ("alert alert-success") .

you can try this code as below =

enter code here

public idValueClass = {
  'alert': true,
  'alert-success': this.idPresent,
  'alert-danger': !this.idPresent,
};

i more suggestion condition on ngClass use tenary then get value on .ts

idValueClass() {
  return this.idValueClass ? 'alert alert-success' : 'alert alert-danger'
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.