52

I have a small expression to check whether 2 objects are different or not, in order to display this element (via adding class name):

<div ngClass='{{JSON.stringify(obj1) != JSON.stringify(obj2) ? "div-show" : ""}}'></div>

The problem is I get this error: Cannot read property 'stringify' of undefined.

What I need a way to work around, or a proper solution if available. Thanks.

PS: I use JSON.stringify() to compare 2 simple objects, nothing fancy here.

3 Answers 3

63

Template code doesn't have access to all javascript, only component properties and methods. I think it would be best to create a 'stringify' method on your component, but you could just set a JSON property:

public constructor() {
  this.JSON = JSON;
}

Also I think your expression is backwards. NgClass takes the css class as the property name and a true/false value to tell whether that class is on the element, and it needs to be in brackets:

<div [ngClass]="{'div-show': JSON.stringify(obj1) != JSON.stringify(obj2)}"></div>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for answering. Your answer and @rashfmnb's are pretty much the same. About the addition, I've experienced many circumstances with ngClass and I find my way of doing is the most solid way to use ngClass. Of course, yours works perfectly, but in some cases it doesn't, compared to mine. One example that [ngClass] cannot work: <div [ngClass]='classNameHolder1' [ngClass]='{"class-name-2": isClassName2}'></div>. If I'm wrong, feel free to correct me.
public JSON : JSON; field should be defined in the component as well to not break AOT
55

2 Years later but, you can do it the Angular Way using the built in pipe 'JsonPipe' from @angular/common

@Component({
  selector: 'json-pipe',
  template: `<div>
    <p>Without JSON pipe:</p>
    <pre>{{object}}</pre>
    <p>With JSON pipe:</p>
    <pre>{{object | json}}</pre>
    </div>`
})

export class JsonPipeComponent {
  object: Object = {foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}};
}

3 Comments

This should be the selected answer
How does the pipe work when using the JSON as a condition for ngClass? The answer doesn't match what the question is asking about?
Wow, so elegant!
6

you can achieve it like this in your component do this.

myjson:any=JSON;

and in you view do it like this

<div ngClass='{{myjson.stringify(obj1) != myjson.stringify(obj2) ? "div-show" : ""}}'></div>

2 Comments

Thanks for answering. Your code works perfectly but @Jason Goemaat's answer seems to be cleaner to me.
my friend no problem

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.