How to check empty object in angular 2 template using *ngIf
JavascriptTypescriptAngularJavascript Problem Overview
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?
Javascript Solutions
Solution 1 - Javascript
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
Solution 2 - Javascript
From the above answeres, following did not work or less preferable:
-
(previous_info | json) != '{}'
works only for{}
empty case, not fornull
orundefined
case -
Object.getOwnPropertyNames(previous_info).length
also did not work, asObject
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
Solution 3 - Javascript
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));
}
Solution 4 - Javascript
Above answers are okay. But I have found a really nice option to use following in the view:
{{previous_info?.title}}
probably duplicated question https://stackoverflow.com/questions/34910928/angular2-error-if-dont-check-if-object-field-exists
Solution 5 - Javascript
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.
Solution 6 - Javascript
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"
Solution 7 - Javascript
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>