如何使用 * ngIf 检查角度2模板中的空对象

我想检查我的对象是否为空,不要渲染我的元素,这是我的代码:

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

但是我的代码错了,最好的方法是什么?

186488 次浏览

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

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));
}

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

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.

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>

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"

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