2

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);
    }
}
13
  • Where does the error points? it should give you at least a file or a line where it happens. It seems like it's not from getAll() method as it seems good to me... Commented Mar 10, 2017 at 9:10
  • Check contents of response.json() in mapBootcamps function. It seems that there is no results property in it Commented Mar 10, 2017 at 9:10
  • Seems like .get('${this.baseUrl}/GetAlleBootcamps', { headers: this.getHeaders() }) is null... As far as there is no DI exceptions, its hard to find a problem. Commented Mar 10, 2017 at 9:11
  • the content of response.json() is an array with the right data from my database in it so i dont think that is the issue. When i did a console.log(response.json()) i get to see the right data in it. Could it be that the date format im using is causing an issue? Commented Mar 10, 2017 at 9:37
  • This is what the console.log looks like Array[1] 0 : Object Begindatum : "/Date(1448146800000)/" Description : "test data" Einddatum : "/Date(1450738800000)/" IdBootcamp : 1 Naam : "Project1" proto : Object length : 1 proto : Array[0] Commented Mar 10, 2017 at 9:39

2 Answers 2

4

I know this is old but I just ran into this issue myself. I'm assuming you were also using the following tutorial:

https://www.barbarianmeetscoding.com/blog/2016/04/02/getting-started-with-angular-2-step-by-step-6-consuming-real-data-with-http/

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!

Sign up to request clarification or add additional context in comments.

Comments

1

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.

6 Comments

When i did it showed that it has an array in it with 1 value and that should be correct since i only have 1 row of dummy data in my database so i dont think that is the issue
can you please add the result of this console.log? Maybe it's just because you try to get results property from the array like if it was an object, so it cant work.
Array[1] 0 : Object Begindatum : "/Date(1448146800000)/" Description : "testdata" Einddatum : "/Date(1450738800000)/" IdBootcamp : 1 Naam : "Project1" proto : Object length : 1 proto : Array[0]
Could it be that the dateformat is giving me issues here?
no, the problem is that you use the array as if it was an object but it's an array, so the results property doesn't exist in it. Date format will also be an issue for parsing after that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.