2017-05-16 72 views
2

誰能與「錯誤:未捕獲的(在承諾):類型錯誤:無法讀取的未定義的屬性‘長’」

"Error: Uncaught (in promise): TypeError: Cannot read property 'length' of undefined 

TypeError: Cannot read property 'length' of undefined 
    at SomeComponent.webpackJsonp.805.SomeComponent.getBList (http://localhost:4200/1.chunk.js:23613:34) 
    at SomeComponent.webpackJsonp.805.SomeComponent.ngOnInit (http://localhost:4200/1.chunk.js:23610:14) 
    at checkAndUpdateDirectiveInline (http://localhost:4200/vendor.bundle.js:11957:19) 
    at checkAndUpdateNodeInline (http://localhost:4200/vendor.bundle.js:13336:17) 
    at checkAndUpdateNode (http://localhost:4200/vendor.bundle.js:13304:16) 
    at debugCheckAndUpdateNode (http://localhost:4200/vendor.bundle.js:13933:59) 
    at debugCheckDirectivesFn (http://localhost:4200/vendor.bundle.js:13874:13) 
    at Object.eval [as updateDirectives] (ng:///SeasonPageModule/SeasonPageComponent_Host.ngfactory.js:16:5) 
    at Object.debugUpdateDirectives [as updateDirectives] (http://localhost:4200/vendor.bundle.js:13859:21) 
    at checkAndUpdateView (http://localhost:4200/vendor.bundle.js:13271:14) 
    at callWithDebugContext (http://localhost:4200/vendor.bundle.js:14259:42) 
    at Object.debugCheckAndUpdateView [as checkAndUpdateView] (http://localhost:4200/vendor.bundle.js:13799:12) 
    at ViewRef_.detectChanges (http://localhost:4200/vendor.bundle.js:11368:63) 
    at RouterOutlet.activateWith (http://localhost:4200/vendor.bundle.js:32580:42) 
    at ActivateRoutes.placeComponentIntoOutlet (http://localhost:4200/vendor.bundle.js:31760:16) 
    at ZoneAwareError (http://localhost:4200/vendor.bundle.js:95038:33) 
    at resolvePromise (http://localhost:4200/vendor.bundle.js:94728:31) 
    at resolvePromise (http://localhost:4200/vendor.bundle.js:94713:17) 
    at http://localhost:4200/vendor.bundle.js:94762:17 
    at ZoneDelegate.invokeTask (http://localhost:4200/vendor.bundle.js:94502:35) 
    at Object.onInvokeTask (http://localhost:4200/vendor.bundle.js:5362:37) 
    at ZoneDelegate.invokeTask (http://localhost:4200/vendor.bundle.js:94501:40) 
    at Zone.runTask (http://localhost:4200/vendor.bundle.js:94378:47) 
    at drainMicroTaskQueue (http://localhost:4200/vendor.bundle.js:94660:35)" 

我試圖從一個JSON得到一個內部數組的值的錯誤幫助文件到我創建的變量。 我的json文件格式如下。

JSON filename: file.json 
    { 
     "A":[ 
     { 
      "id": "123", 
      "title": "title of A", 
      "type": "asf", 
      "B": [ 
      { 
       "id": "1", 
       "title": "title1" 
      }, 
      { 
       "id": "2", 
       "title": "title2" 
      } 
      ] 
     ] 
    } 

我創建了幾個模型來存儲值

A.model.ts 
import {B} from './b.model'; 

export interface A { 

    type?; 

    id?; 

    title?; 

    b?: B[]; 

} 

B.model.ts 
export interface B { 

    id?; 

    title?; 

} 

我的服務返回JSON具有以下

someService.service.ts 

import {A} from '../model/a.model'; 
constructor(private _http: Http, private _authService: AuthService) {} 

    get() { 
    return this._http.get('app/file.json') 
        .toPromise() 
        .then(res => <A[]> res.json().showList) 
        .then(A => { return A; }); 
    } 

在component.ts我寫了下面的碼。

<somename>.component.ts 

import { Component, OnInit } from '@angular/core'; 
import { Routes, Router } from '@angular/router'; 
import {Observable} from 'rxjs'; 

import {A} from '../../shared/model/a.model'; 
import {SomeService} from '../../shared/service/someService.service'; 
import {B} from '../../shared/model/b.model'; 
import {Location} from '@angular/common'; 

class AList implements A { 
    constructor(public title?, public id?, public type?, public bList?: B[]) {} 
} 
class BList implements B { 
    constructor(public title?, public id?) {} 
} 

@Component({ 
    selector: 'ms-season-page', 
    styleUrls: [], 
    template: require('./season-page.component.html') 
}) 
export class SomeComponent implements OnInit { 

    b: B = new BList(); 

    bArray: B[] = []; 

    aArray: A[]; 

    constructor(private router: Router, private someService: SomeService) { 
    } 

    ngOnInit() { 
    this.someService.get().then(a => this.aArray = a); 
    this.bArray = this.getBList(this.aArray); 
    } 

    getBList(aArray: AList[]): B[] { 
    let bList: B[] = []; 
    for(let j=0; j<aArray.length; j++) { 
     for (let i=0; i<aArray[j].seasonList.length; i++) { 
      let b = new BList(aArray[j].B[i].title, aArray[j].B[i].id); 
      bList.push(b); 
     } 
    } 
    return bList; 
    } 
} 

任何人都可以幫我說明我在做什麼錯誤嗎?或者有沒有辦法獲得'B'數組值。

在此先感謝。

+0

可能更好地寫成'this._http.get('app/file.json')。map(res => res.json()。showList).toPromise()'。最後保留從「Observable」到「Promise」的轉換,並利用本地可觀察運算符。 –

+0

嗨尼爾Lunn, 我已經嘗試了你建議的方式,並使得差異很大,錯誤仍然是相同的。 其實我的問題是在 'getBList(aArray:AList []):B [] { let bList:B [] = []; (let i = 0; i Krish

+1

當然這是一個問題,因爲'.get()'方法仍然是「異步」。您需要類似地操作'.then()'或「內部」。 I.E下一行代碼是**不**等待前一個。 –

回答

3

問題是this.someService.get是異步的,您要訪問它的結果,如果它是同步的:

this.someService.get().then(a => this.aArray = a); // This is asynchronous 
this.bArray = this.getBList(this.aArray); // This will be called before `this.aArray` is set to anything. Now `this.aArray` will be undefined 

解決方法是在異步方法的回調使用this.aArray

this.someService.get().then(a => { 
    this.aArray = a; 
    this.bArray = this.getBList(this.aArray); // Now `this.aArray` will have some value provided `someService.get()` returns something 
}); 
+0

你說得對。但是soneService.get()並不像Neil Lunn上面解釋的那樣返回一個值。 – Krish

+0

'someService.get()'返回一個承諾,但該承諾是否解析爲某個值取決於從_http.get('app/file.json')返回的數據結構。 – Saravana

+0

謝謝。我沒有改變service.ts中的任何內容,並且我已經按照您的建議在組件中添加了一行,並且它可以正常工作。感謝堆。 – Krish

-1

這個res.json().showList是錯誤的。 json返回一個承諾。承諾沒有showList成員。

修復

   toPromise() 
       .then(res => res.json()) 
       .then(A => { return A.showList; }); 

更多

An assertions should not be considered without caution

+0

其實我正確修改。我的服務是一樣 的get(){ 回報this._http.get( '應用程序/ file.json') .toPromise() 。然後(RES => res.json()。A)。然後 (A => {return A;}); } 當我使用這個時,我可以得到'A'的值(即A的id,標題和類型),但不能得到B的值。 – Krish

+0

我在其他場景中使用了相同的方法這工作正常。 – Krish

相關問題