7

i'm trying to use angular 4 to call to a dummy web api, here is my component

export class AppComponent {
    title = 'app';
    url = 'https://api.ipify.org/?format=json';
    results: any;

    constructor(private http: Http) {
        this.getData().subscribe(data => {
            this.results = data.json();
        })
    }

    getData() {
        return this.http.get(this.url);
    }

}


but when i try to display it i get the result but also a screen of error

ERROR TypeError: Cannot read property 'ip' of undefined

what i want to understand is why it is shown because after a split second the data is well displayed .

Hamidreza
  • 1,465
  • 12
  • 31
Ayoub Idelhoussain
  • 635
  • 4
  • 9
  • 23

7 Answers7

9

In your *ngFor you can change it to *ngFor="let r of results | async"

Your problem is that the data isn't there yet, so it can't read the id property.

If you use the async pipe, it should wait for the data to come before displaying it.

8

Make use of Elvis Operator instead i:e safe operator

{{results?.ip}} 
Rahul Singh
  • 19,030
  • 11
  • 64
  • 86
5

You get this error also if you add your component to the import array instead of the declaration array.

@NgModule({
  imports: [
    ...,
    someComponent
  ],

  declarations: [...],
})
export class MainModule { }

Should be

@NgModule({
  imports: [
    ...,
  ],

  declarations: [...,someComponent],
})
export class MainModule { }
Thom Kiesewetter
  • 6,703
  • 3
  • 28
  • 41
2

put {{results}} in your html part. You'll see the value the server give you.

Maybe you should use *ngfor when you get the values and use an async pipe on it to display it correctly

amin89
  • 558
  • 1
  • 8
  • 26
1

Change this

import 'rxjs/add/operator/map';


this.getData().subscribe(data => {
  this.results = data;
 });
}

getData() {
     return this.http.get(this.url).map(resp => resp.json());
}

and add this in the template

*ngIf="results" 
alehn96
  • 1,363
  • 1
  • 13
  • 23
1
import 'rxjs/add/operator/map';


this.getData().subscribe(data => {
  this.results = data;
 });
}

getData() {
     return this.http.get(this.url).map(resp => resp.json());
}

HTML part

*ngFor="let r of results | async"
 <p>{{r}}</p>
amin89
  • 558
  • 1
  • 8
  • 26
1

if you have more than one property you can use a class and inject them there , then it would be no problem . otherwise if you have just one single variable and u want it to be displayed pls use the safe navigation operator user?.name