Reputation: 481
So i just started learning Angular2 and im trying to get the data i have on my database and display it on my indexpage but everytime i try to do so i get an error saying "Cannot read property 'map' of undefined" and i have no idea why i have been searching for hours. Can someone please help me out.
import { Component } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { Injectable } from '@angular/core';
import { Bootcamp } from './Bootcamp';
const BOOTCAMP: Bootcamp[] = [];
@Injectable()
export class Bootcamptest {
private baseUrl: string = 'http://localhost:54220/Bootcampdata';
constructor(private http: Http) { }
getAll(): Observable<Bootcamp[]> {
let bootcamp$ = this.http
.get(`${this.baseUrl}/GetAlleBootcamps`, { headers: this.getHeaders() })
.map(mapBootcamps)
.catch(handleError);
return bootcamp$;
}
private getHeaders() {
let headers = new Headers();
headers.append('Accept', 'application/json');
return headers;
}
}
function mapBootcamps(response: Response): Bootcamp[] {
// uncomment to simulate error:
// throw new Error('ups! Force choke!');
// The response of the API has a results
// property with the actual results
return response.json().results.map(toBootcamp)
}
function toBootcamp(r: any): Bootcamp {
let bootcamp = <Bootcamp>({
id: extractId(r),
naam: r.name,
description: r.description,
begindatum: r.begindatum,
einddatum: r.einddatum
});
console.log('Parsed bootcamp:', bootcamp);
return bootcamp;
}
// to avoid breaking the rest of our app
// I extract the id from the person url
function extractId(bootcampData: any) {
let extractedId = bootcampData.url.replace('http://localhost:54220/Bootcampdata/Getallebootcamps', '').replace('/', '');
return parseInt(extractedId);
}
function mapBootcamp(response: Response): Bootcamp {
// toBootcamp looks just like in the previous example
return toBootcamp(response.json());
}
// this could also be a private method of the component class
function handleError(error: any) {
// log error
// could be something more sofisticated
let errorMsg = error.message || `Error met het laden van data!`
console.error(errorMsg);
// throw an application level error
return Observable.throw(errorMsg);
}
The component class
import { Component, OnInit } from '@angular/core';
import { Bootcamp } from './Bootcamp';
import { Bootcamptest } from './Bootcamptest';
@Component({
selector: 'my-bootcamptest',
template: `
<section>
<section *ngIf="isLoading && !errorMessage">
Loading our hyperdrives!!! Retrieving data...
</section>
<ul>
<!-- this is the new syntax for ng-repeat -->
<li *ngFor="let person of people">
<a>
{{bootcamp.naam}}
</a>
</li>
</ul>
<section *ngIf="errorMessage">
{{errorMessage}}
</section>
</section>
`
})
export class Bootcamplistcomponent implements OnInit {
bootcamp: Bootcamp[] = [];
errorMessage: string = '';
isLoading: boolean = true;
constructor(private bootcamptest: Bootcamptest) { }
ngOnInit() {
this.bootcamptest
.getAll()
.subscribe(
/* happy path */ p => this.bootcamp = p,
/* error path */ e => this.errorMessage = e,
/* onComplete */() => this.isLoading = false);
}
}
Upvotes: 2
Views: 14022
Reputation: 369
I know this is old but I just ran into this issue myself. I'm assuming you were also using the following tutorial:
I was stuck for a long time until I started to dissect my equivalent of "mapBootcamps". What I found was that the ".results" part of the following line: "return response.json().results.map(toBootcamp)" was returning a value of undefined. Thus, when the ".map(toBootcamp)" method is called, it throws the error "Cannot read property 'map' of undefined".
To fix the problem, I simply removed ".results" from the line "return response.json().results.map(toBootcamp)" and it worked!
Hope that helps!
Upvotes: 4
Reputation: 8731
Your problem seems to be coming from your API.
In the mapBootcamps
you commented that every API response had a results
property but it seems like sometimes it doesn't.
Your console.log
showed that you had an array
of object
, so results does not exist, it is null
.
If you change response.json().results.map(toBootcamp)
to response.json()[0].results.map(toBootcamp)
it'll work, but I don't think that's what you have to do, you should create a method to handle data as an array, or change the return format of your API to an object.
Upvotes: 1