1
votes

I am trying to display an object values in angular 2 templates and specifically when I try to get an object array using ngFor gives me an error saying

EXCEPTION: Uncaught (in promise): Error: Error in ./SgDetailComponent class SgDetailComponent - inline template:15:7 caused by: Cannot read property 'tags' of undefined I can get string/number property but not object property.

Here's my component.ts

@Component({
  selector: 'app-sg-detail',
  templateUrl: './sg-detail.component.html',
  styleUrls: ['./sg-detail.component.scss', '../../app.component.scss']
})
export class SgDetailComponent implements OnInit {

  errorMessage: string;
  sgDetail: Sg;
  groupId: string;
  ipPermissions: IpPermissions[];
  userIdGroupPairs: UserIdGroupPairs[];
  opPermissionsEgress: IpPermissionsEgress[];
  tags: Tags[];

  constructor(private activatedRoute: ActivatedRoute, private sgService: SgService) { }

  ngOnInit() {
    this.activatedRoute.params.subscribe((params: Params) => {
      let groupId = params['groupId'];
      this.groupId = groupId;
    });
    this.getSgsByGroupId(this.groupId);
  }
  getSgsByGroupId(groupId: String) {
    this.sgService.getSgByGroupId(groupId)
    .subscribe(
      sgDetail => this.sgDetail = sgDetail,
      error => {
        this.errorMessage = error.getMessage();
        console.error(error.getDescription());
      });
  }
}

here's my component.html

 <div class="container app_container">
    <ul class="app_list">
        <li *ngIf="sgDetail" class="app_list-item">
            <p>GroupId: {{sgDetail.groupId}}</p>
            <p>GroupName: {{sgDetail.groupName}}</p>
        </li>
        <li *ngFor="let tag of sgDetail.tags" class="app_list-item">
             //this loop sgDetail.tags errors out 
        </li>
    </ul>
 </div>

and here's my model.ts

export interface Sg {
 ownerId: number;
 groupName: string;
 groupId: string;
 description: string;
 ipPermissions: IpPermissions[];
 ipPermissionsEgress: IpPermissionsEgress[];
 vpcId: string;
 tags: Tags[];
}

export interface IpPermissions {
 ipProtocol: string;
 fromPort: number;
 toPort: number;
 userIdGroupPairs: UserIdGroupPairs[];
 ipRanges: Array<number>;
 prefixListIds: Array<number>;
}

export interface UserIdGroupPairs {
 userId: number;
 groupName: string;
 groupId: string;
 vpcId: string;
 vpcPeeringConnectionId: string;
 peeringStatus: string;
}

export interface IpPermissionsEgress {
 ipProtocol: string;
 fromPort: number;
 toPort: number;
 userIdGroupPairs: UserIdGroupPairs[];
 ipRanges: Array<number>;
 prefixListIds: Array<number>;
}

export interface Tags {
 key: string;
 value: string;
}
2
I think when you use let sgDetail of sgDetail.tags you're reassigning sgDetail, losing the reference for the property you set on your component. Try using another name, like let tag of sgDetail.tags - Alexandre Angelim
@AlexandreAngelim Still doesn't work.I think the error comes while it tries to get tags property . - amulamul
I don't see anything wrong there. How about a little debugging? console.log sgDetail just after assigning it on getSgsByGroupId. - Alexandre Angelim

2 Answers

1
votes

The error is caused by Asynchorouse call --> getSgsByGroupId, which means the result ofgetSgsByGroupId hasn't come when angular renders the view.

try the safe way angular have provided:

<li *ngFor="let tag of sgDetail?.tags" class="app_list-item">
</li>
-1
votes

Try this:-

<ul *ngIf="let tag of sgDetail">
  <li>tag.groupId</li>
<ul>

But before looping or using *ngIf you should print sgDetail as a json like this:-
  {{sgDetail | json}}