【问题标题】:Angular2 Map "Cannot read property 'map' of undefined"Angular2 Map“无法读取未定义的属性'map'”
【发布时间】:2017-05-02 10:37:38
【问题描述】:

所以我刚开始学习 Angular2,我试图获取我在数据库中的数据并将其显示在我的索引页上,但每次我尝试这样做时,我都会收到一条错误消息“无法读取未定义的属性 'map'”和我不知道为什么我一直在寻找几个小时。谁能帮帮我。

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);
}

组件类

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);
    }
}

【问题讨论】:

  • 错误点在哪里?它应该至少给你一个文件或发生它的一行。它似乎不是来自getAll() 方法,因为它对我来说似乎很好......
  • mapBootcamps函数中检查response.json()的内容。里面好像没有results属性
  • 好像.get('${this.baseUrl}/GetAlleBootcamps', { headers: this.getHeaders() }) 为空……只要没有DI 异常,就很难找到问题了。
  • response.json() 的内容是一个数组,其中包含来自我的数据库的正确数据,所以我认为这不是问题。当我执行 console.log(response.json()) 时,我可以看到其中的正确数据。难道是我使用的日期格式导致了问题?
  • 这是 console.log 的样子 Array[1] 0 : Object Begindatum : "/Date(1448146800000)/" 描述 : "test data" Einddatum : "/Date(1450738800000)/" IdBootcamp:1 Naam:“Project1”proto:对象长度:1 proto:Array[0]

标签: angular


【解决方案1】:

我知道这已经过时了,但我自己也遇到了这个问题。我假设您也在使用以下教程:

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

我被困了很长时间,直到我开始剖析我的“mapBootcamps”。我发现以下行的“.results”部分:“return response.json().results.map(toBootcamp)”正在返回一个未定义的值。因此,当调用“.map(toBootcamp)”方法时,会抛出错误“Cannot read property 'map' of undefined”。

为了解决这个问题,我只是从“return response.json().results.map(toBootcamp)”行中删除了“.results”,它就成功了!

希望有帮助!

【讨论】:

    【解决方案2】:

    您的问题似乎来自您的 API。

    mapBootcamps 中,您评论说每个 API 响应都有一个 results 属性,但有时似乎没有。

    您的console.log 表明您有一个objectarray,所以结果不存在,它是null

    如果您将response.json().results.map(toBootcamp) 更改为response.json()[0].results.map(toBootcamp),它会起作用,但我认为您不必这样做,您应该创建一个将数据作为数组处理的方法,或者更改您的返回格式对象的 API。

    【讨论】:

    • 当我这样做时,它显示它有一个包含 1 个值的数组,这应该是正确的,因为我的数据库中只有 1 行虚拟数据,所以我认为这不是问题跨度>
    • 你能添加这个console.log的结果吗?也许只是因为你试图从数组中获取 results 属性,就像它是一个对象一样,所以它不能工作。
    • Array[1] 0 : Object Begindatum : "/Date(1448146800000)/" Description : "testdata" Einddatum : "/Date(1450738800000)/" IdBootcamp : 1 Naam : "Project1" proto:对象长度:1 proto:Array[0]
    • 可能是日期格式在这里给我带来了问题吗?
    • 不,问题是您使用数组,就好像它是一个对象但它是一个数组,所以结果属性不存在其中。之后日期格式也将成为解析的问题。
    猜你喜欢
    • 2022-07-11
    • 2022-07-27
    • 2023-01-19
    • 2017-08-15
    • 2018-12-23
    • 1970-01-01
    • 2023-01-03
    • 2018-08-23
    • 2023-01-11
    相关资源
    最近更新 更多