hesham shawky
hesham shawky

Reputation: 1151

cannot read property of undefined angular 7

I am getting many errors at the dev tools console when adding a service into my component but the code still working but I want to get rid of from these errors

This's the service:

 getPagesData(pageSlug: string): Observable<any[]> {
    return this._http.get<any[]>(`${environment.apiUrl}wp/v2/pages/?slug=${pageSlug}`);
  }

This is the component:

import { Component, OnInit } from '@angular/core';
import { DataService } from 'src/app/services/data.service';

@Component({
  selector: 'app-membership',
  templateUrl: './membership.page.html',
  styleUrls: ['./membership.page.scss'],
})
export class MembershipPage implements OnInit {


  public pageContent: any = {};
  public content: string;

  constructor(
    private _data: DataService
  ) { }

  ngOnInit() {
    this._data.getPagesData('memberships')
      .subscribe(
        page => this.pageContent = page[0]
      )
  }

  getContent(): string {
    return this.pageContent.content.rendered.replace(/\[(.+?)\]/g, "");
  }

}

What cause the errors is the getContent() method! it says that is the .rendered is an undefined property but it doses defined on the API!

I have searched on that problem and most of the solutions I found it's about using the symbol ? at HTML template but I can't use that in the component itself.

Upvotes: 1

Views: 18069

Answers (2)

Alexander Staroselsky
Alexander Staroselsky

Reputation: 38777

If you are calling getContent() in the HTML/template, you can most likely avoid this error by either:

Making pageContent initially null and using *ngIf to only display the content once it has asynchronously resolved:

Component:

public pageContent: any = null;

Template:

<div *ngIf="pageContent">{{getContent()}}</div>

Or you could instead RxJS operators such as map() and the async pipe:

Component:

import { Component, OnInit } from '@angular/core';
import { DataService } from 'src/app/services/data.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({
  selector: 'app-membership',
  templateUrl: './membership.page.html',
  styleUrls: ['./membership.page.scss'],
})
export class MembershipPage implements OnInit {
  public pageContent: Observable<string>;
  public content: string;

  constructor(private _data: DataService) { }

  ngOnInit() {
    this.pageContent = this._data.getPagesData('memberships')
      .pipe(
        map(page => page[0].content.rendered.replace(/\[(.+?)\]/g, ""))
      );
  }
}

Template:

<div>{{pageContent | async}}</div>

That being said, you should probably have additional checks to ensure each sub-property is available prior to accessing it, but usually this type of error is because you are attempting to access the contents before they have resolved.

Hopefully that helps!

Upvotes: 4

Pardeep Jain
Pardeep Jain

Reputation: 86740

Yes, you cannot use ? Elvis (Safe navigation) operator in the component itself because it is designed for view part only.

But you can add some check in the component too to avoid such errors like -

getContent(): string {
    const dataToReturn = this.pageContent && this.pageContent.content && this.pageContent.content.rendered.replace(/\[(.+?)\]/g, "");
    return dataToReturn
  }

.rendered is an undefined property

Also, This error may produce you have defined pageContent = {} so on {} neither content nor rendered exist , may be that is also the reason to exist such errors.

Angular recommend to strongly typecast your data before use.

Upvotes: 2

Related Questions