100

I want to check if my object is empty dont render my element, and this is my code:

<div class="comeBack_up" *ngIf="previous_info != {}">
  <a [routerLink]="['Inside_group_page',{'name':previous_info.path | dotTodash }]">
    {{ previous_info.title }}
  </a>
</div>

but my code is wrong, what is the best way to do this?

3
  • I'm still using a custom function for that.. stackoverflow.com/a/33319704/3779853 (defined as an exported function somewhere) Commented Jan 28, 2017 at 20:38
  • Hugely important question. If a JSON object of data is returned for a component/screen, ngFor/loop thru it and display it. If JSON object is empty, display different screen. Commented Sep 19, 2018 at 15:21
  • try=> *ngIf="myVar?.length" Commented May 14, 2022 at 10:00

9 Answers 9

175

This should do what you want:

<div class="comeBack_up" *ngIf="(previous_info | json) != ({} | json)">

or shorter

<div class="comeBack_up" *ngIf="(previous_info | json) != '{}'">

Each {} creates a new instance and ==== comparison of different objects instances always results in false. When they are convert to strings === results to true

Plunker example

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

4 Comments

The json pipe like all other pipes provided with the Angular package are globally available without additional registration.
That doesn't seem related to the code of your question or my answer. What Angular2 version are you using?
If your object would have a circular reference, this code does not work. Angular will throw a ERROR TypeError: Converting circular structure to JSON exception.
Just a heads up if this doesn't work for someone. I had to add !== and it worked.
76

From the above answeres, following did not work or less preferable:

  • (previous_info | json) != '{}' works only for {} empty case, not for null or undefined case
  • Object.getOwnPropertyNames(previous_info).length also did not work, as Object is not accessible in the template
  • I would not like to create a dedicated variable this.objectLength = Object.keys(this.previous_info).length !=0;
  • I would not like to create a dedicated function

    isEmptyObject(obj) {
       return (obj && (Object.keys(obj).length === 0));
    }
    

Solution: keyvalue pipe along with ?. (safe navigation operator); and it seems simple.

It works well when previous_info = null or previous_info = undefined or previous_info = {} and treats as falsy value.

<div  *ngIf="(previous_info | keyvalue)?.length">

keyvalue - Transforms Object or Map into an array of key value pairs.

?. - The Angular safe navigation operator (?.) is a fluent and convenient way to guard against null and undefined

DEMO: demo with angular 9, though it works for previous versions as well

7 Comments

I think this is the best solution, since putting the function: isEmptyObject() in your template causes it to be called whenever change detection occurs. I've found this to happen quite a bit, such as simply clicking anywhere on the page.
keyvalue)?.length does not work: Identifier 'length' is not defined. 'null' does not contain such a member
@marcel could you show your code sample? Because, the Angular safe navigation operator, ?, guards against null and undefined values in property paths.
@Sumit *ngIf="({} | keyvalue)?.length" -> shows the error. I am using Angular 9.
This is brilliant, a much more elegant solution than converting to string to make a comparison IMO. Thank you!
|
42

You could also use something like that:

<div class="comeBack_up" *ngIf="isEmptyObject(previous_info)"  >

with the isEmptyObject method defined in your component:

isEmptyObject(obj) {
  return (obj && (Object.keys(obj).length === 0));
}

6 Comments

What is passed object is null or undefined? Will this expression work? In case of null will break and throw an exception.
@PriyankSheth you're right. I extended the test in the isEmptyObject method to check obj is null or undefined...
This was very useful, 10x!
In angular 4, for someone it isnt working due to datatype error, all you need to do is define datatype in fn argument like so: isEmptyObject(obj:any) Good answer btw, +1
calling function in ngIf is not a good practice. causes infinite calls and will affect performance of app
|
15

Above answers are okay. But I have found a really nice option to use following in the view:

{{previous_info?.title}}

probably duplicated question Angular2 - error if don't check if {{object.field}} exists

1 Comment

This works if you're absolutely sure the object's gonna have a title prop in its non-empty state
4

This worked for me:

Check the length property and use ? to avoid undefined errors.

So your example would be:

<div class="comeBack_up" *ngIf="previous_info?.length">

UPDATE

The length property only exists on arrays. Since the question was about objects, use Object.getOwnPropertyNames(obj) to get an array of properties from the object. The example becomes:

<div class="comeBack_up" *ngIf="previous_info  && Object.getOwnPropertyNames(previous_info).length > 0">

The previous_info && is added to check if the object exists. If it evaluates to true the next statement checks if the object has at least on proporty. It does not check whether the property has a value.

2 Comments

Very nice. I have the fundamental case of "If a JSON object has data in it, ngFor/loop thru it and display. If JSON is empty, display "No matches" screen."
@Loke Object is undefined when it comes to HTML
2

A bit of a lengthier way (if interested in it):

In your typescript code do this:

this.objectLength = Object.keys(this.previous_info).length != 0;

And in the template:

ngIf="objectLength != 0"

Comments

1

Best way is to create a function that will check whether an object is empty or not. in your Typescript file do this:

    isEmptyObject(obj: any): boolean {
  return Object.keys(obj).length === 0;
}

this function will take any type of object as an argument and return true or false depending on whether it has any enumerable property or not.

and then of course, the HTML file of your component:

<div class="comeBack_up" *ngIf="!isEmptyObject(previous_info)">
  <a [routerLink]="['Inside_group_page',{'name':previous_info.path | dotTodash }]">
    {{ previous_info.title }}
  </a>
</div>

Comments

0

Just for readability created library ngx-if-empty-or-has-items it will check if an object, set, map or array is not empty. Maybe it will help somebody. It has the same functionality as ngIf (then, else and 'as' syntax is supported).

arrayOrObjWithData = ['1'] || {id: 1}

<h1 *ngxIfNotEmpty="arrayOrObjWithData">
  You will see it
</h1>

 or 
 // store the result of async pipe in variable
 <h1 *ngxIfNotEmpty="arrayOrObjWithData$ | async as obj">
  {{obj.id}}
</h1>

 or

noData = [] || {}
<h1 *ngxIfHasItems="noData">
   You will NOT see it
</h1>

Comments

0

Using an includes statement verifies that the object is neither null or an empty set.

<div class="comeBack_up" *ngIf="!['null','{}'].includes(previous_info | json)">

Comments

Your Answer

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