brainmonger
brainmonger

Reputation: 687

Angular ngFor variable assignment

I have the following:

<div *ngFor="let item of order.items">

I need to display the result, for example:

{{item.product.category.availability.selected.name.value}}
{{item.product.category.availability.selected.id.value}}

I would like to ideally assign this whole portion to a variable inside my template:

let item = item.proproduct.category.availability.selected

So I can display data like this instead throughout my template (way shorter):

{{item.name.value}}
{{item.id.value}}

Is there a way to do this?

Upvotes: 4

Views: 1860

Answers (3)

Sergio Escudero
Sergio Escudero

Reputation: 1894

The destructuring feature is not available in angular template. Check the issue in the git hub repository

One solution would be creating a pipe to format this. For example:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'formatValues'})
export class FormatValues implements PipeTransform {

  //Destructuring in the first parameter which has the item value
  transform({ product: { category: { availability: { selected :{ name: { value } } } } } }: any, args?: any[]): string {
    return value;
  }
}

import and declare it in the module:

import { FormatValues } from './values.pipe';


@NgModule({
  declarations: [
    AppComponent,
    FormatValues
  ],
  ...
})

Finally use the Pipe:

<div *ngFor="let item of order.items">
   {{item | formatValues}}
</div>

Also if you want to prevent a pipe, just create a function in the component and call it:

{{formatValue(item)}}

in your ts:

formatValue({product:{ category:{availability:{selected:{ name:{ value }}}}}}: any): string {
  return value;
}

Upvotes: 3

Birches
Birches

Reputation: 101

You cannot define a shorthand variable like this within a template in Angular.

The nearest thing I can think of

<div *ngFor="let item of order.items">
    <ng-container *ngIf="item.product.category.availability.selected as value">
         ...
       {{value}}
         ...
    </ng-container>
</div>

But that's not exactly recommended, it's more of a workaround.

A more "Angular" way would be to break down or format the object in the component code.

One way of doing this:

Component:

...
export class ComponentClass {
    ...
    getNestedProperty(nestedItem): string {
        return nestedItem.product.category.availability.selected.name.value;
    }
}
...

Template:

<div *ngFor="let item of order.items">
...
{{getNestedProperty(item)}}
...
</div>

Others have suggested creating a sub-component and that seems like a good idea as well.

https://angular.io/guide/styleguide#put-presentation-logic-in-the-component-class

Upvotes: 2

Suhag Lapani
Suhag Lapani

Reputation: 695

<div *ngFor="let item of order?.items?.product?.category?.availability?.selected
"> 

You can write like this

Now you can access

{{item.name.value}} {{item.id.value}}

Upvotes: -1

Related Questions