Angular 2+ NgOnInit assigning value to input array but throws an error of undefined

272 Views Asked by At

I have a component which expects some inputs, the input that i care about is the feedList. In the feedList there are feed objects with their own data filled in. However, depending on the feed sometimes some data are not provided when the object is created, hence the undefined.

My problem is that in my HTML i have an ngFor and display the feeds. But some of the feeds for instance, they don't have the

feed.thirdColumn.kIcon.extraClass

defined, hence when the component renders it will complain about undefined. Here is the complete HTML

<ng-container *ngIf="feedList">
    <div class="container">
        <div class="row feed-container" *ngFor="let feedItem of feedList">
            <div class="kendo-tooltip" kendoTooltip [title]="feedItem.tooltipText" showOn="{{feedItem.tolltipVisible}}">
            <div class="feed-item">
                <div class="col-sm-4 column-inlineBlock feed-avatar">
                    <span>
                        <k-icon [icon]=" { type: 'image', src: '000004.png', extraClass: 'feed-icon'}"></k-icon>
                    </span>
                </div>
                <div class="col-sm-7 column-inlineBlock main-feed-content" (click)="onClickSecondColumn(feedItem)">
                    <div class="title"><strong>{{feedItem.secondColumn.title}}</strong></div>
                    <div class="description">{{feedItem.secondColumn.description}}</div>
                    <div class="footer" *ngIf="!feedItem.secondColumn.footer.isTimeAgo">{{feedItem.secondColumn.footer.value}}</div>
                    <div class="footer time-ago" *ngIf="feedItem.secondColumn.footer.isTimeAgo">
                        <k-icon [icon]="{type: feedItem.secondColumn.footer.icon.type, name: feedItem.secondColumn.footer.icon.name, extraClass: ['icon-clock' +  feedItem.secondColumn.footer.icon.extraClass]}"></k-icon>
                        {{ feedItem.secondColumn.value | timeAgo }}
                    </div>
                </div>
                <div class="col-sm-1 column-inlineBlock third-col" *ngIf="!isTwoColumn" (click)="onClickThirdColumn(feedItem)">
                    <div class="third-col-wrapper">
                        <span class="icon-indicator {{feedItem.thirdColumn.status}}">
                            <k-icon [icon]="{type: feedItem.thirdColumn.kIcon.type, name: feedItem.thirdColumn.kIcon.name, extraClass: ['icon-number' + feedItem.thirdColumn.kIcon.extraClass]}"></k-icon>
                    </span>
                    <span class="number-indicator">
                        <strong id="value-indicator">{{feedItem.thirdColumn.value}}</strong>
                    </span>
                    </div>
                </div>
            </div>
        </div>
        </div>
    </div>
</ng-container>

So all i care about is getting rid of the undefined error from the console. What i did so far is this.

import { Component, OnInit, ViewEncapsulation, Input, AfterViewInit, HostBinding, OnChanges, SimpleChanges } from '@angular/core';
import { IKFeed } from '../models/k-feed-list.model';
import { KUtilsService as Utils } from 'ng-k-utils';

@Component({
  selector: 'k-feed',
  templateUrl: './ng-k-feed.component.html',
  encapsulation: ViewEncapsulation.None,
})
export class KFeedComponent implements OnInit {

  @Input() isTwoColumn: boolean;
  @Input() feedList: IKFeed[];

  constructor() {
    if (this.feedList)  {
      this.feedList.map(feed => {
        if (feed.thirdColumn.kIcon.extraClass === undefined) {
          console.log('constructor');
        }
      });
    }
   }

  ngOnInit(): void {
    if (Utils.isDefined(this.feedList))  {
      this.feedList.map(feed => {
        if (feed.tooltipText) {
          feed.tolltipVisible = 'hover';
        } else {
          feed.tolltipVisible = 'none';
        }
        if (feed.thirdColumn.kIcon.extraClass === undefined) {
          feed.thirdColumn.kIcon.extraClass = '';
          console.log('ngOnInit');
        }

        if (feed.thirdColumn.kIcon.extraClass === undefined) {
          feed.secondColumn.footer.icon.extraClass = '';
          console.log('ngOnInit');
        }
      });
    }

  }


  public onClickThirdColumn(feedItem: IKFeed) {
    if (Utils.isDefined(feedItem.thirdColumn.actionClickTrigger)) {
      feedItem.thirdColumn.actionClickTrigger();
    }
  }

  public onClickSecondColumn(feedItem: IKFeed) {
    if (Utils.isDefined(feedItem.secondColumn.actionClickTrigger)) {
      feedItem.secondColumn.actionClickTrigger();
    }
  }

}

Which it console logs the ngoninit and sets the values and the HTML is displayed well. However, i still get the errors in the console log saying that property feed.bla.bla.extraClass is undefined. I tried to use the constructor and check for undefined of extraClass but for some reason when the constructor runs, the feedList(input) is not populated. What exactly should i do to overcome this problem?

1

There are 1 best solutions below

1
On BEST ANSWER

Have you tried the Elvis operator?

  • In Typescript it's called optional chaining operator. Used in the controller of an Angular project.

  • In Angular it's called safe navigation operator. Used in the template of an Angular project.

In both the cases it can be used like feed?.bla?.bla?.extraClass. It makes sure the parent property is defined before trying to access it's children properties.