Jsonファイルからserviceファイルで受け取ったオブジェクトの配列があります。コンポーネントでサブスクライブして繰り返し処理しようとすると、次のエラーが発生します。
EXCEPTION: Error in app/dashboard/features/fleet/fleetControlPanel/fleetControlPanelTemplate.html:38:14BrowserDomAdapter.logError @ browser_adapter.ts:78BrowserDomAdapter.logGroup @ browser_adapter.ts:89ExceptionHandler.call @ exception_handler.ts:53(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.ts:100NgZone.runGuarded @ ng_zone.ts:216outsideHandler @ dom_events.ts:16ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
EXCEPTION: TypeError: Cannot read property 'length' of undefined
TypeError: Cannot read property 'length' of undefined
at FleetSummaryComponent.ngOnChanges (fleetSummaryComponent.ts:62)
at DebugAppView._View_FleetControlPanelComponent2.detectChangesInternal (FleetControlPanelComponent.template.js:755)
at DebugAppView.AppView.detectChanges (view.ts:243)
at DebugAppView.detectChanges (view.ts:345)
at DebugAppView.AppView.detectContentChildrenChanges (view.ts:261)
at DebugAppView._View_FleetControlPanelComponent0.detectChangesInternal (FleetControlPanelComponent.template.js:326)
at DebugAppView.AppView.detectChanges (view.ts:243)
at DebugAppView.detectChanges (view.ts:345)
at DebugAppView.AppView.detectViewChildrenChanges (view.ts:267)
at DebugAppView._View_FleetOperateComponent2.detectChangesInternal (FleetOperateComponent.template.js:891)
TypeError: Cannot read property 'length' of undefined
at FleetSummaryComponent.ngOnChanges (http://localhost:3000/app/dashboard/features/fleet/fleetSummary/fleetSummaryComponent.js:46:41)
at DebugAppView._View_FleetControlPanelComponent2.detectChangesInternal (FleetControlPanelComponent.template.js:755:61)
at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14)
at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:289:44)
at DebugAppView.AppView.detectContentChildrenChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:215:37)
at DebugAppView._View_FleetControlPanelComponent0.detectChangesInternal (FleetControlPanelComponent.template.js:326:8)
at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14)
at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:289:44)
at DebugAppView.AppView.detectViewChildrenChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:220:34)
at DebugAppView._View_FleetOperateComponent2.detectChangesInternal (FleetOperateComponent.template.js:891:8)
誰かが私に言うことができますか、間違いは何ですか、または反復する他の方法はありますか?ありがとう
サービスファイル
import {Injectable} from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class FleetSummaryService {
private url = 'app/dashboard/features/fleet/fleetControlPanel/fleetdataBase.json';
constructor(private _http: Http){
}
getFleetSummary(): Observable<any[]> {
return this._http.get(this.url)
.map((response: Response) => <any[]>response.json())
.do(data => console.log("Data received: " + JSON.stringify(data)))
.catch(this.handleError);
}
private handleError(error: Response){
console.error(error)
return Observable.throw(error.json().error || "Server error");
}
}
コンポーネントファイル
import {Component, OnInit, Input, OnChanges} from '@angular/core';
import {ROUTER_DIRECTIVES} from '@angular/router-deprecated';
import {FleetSummaryService} from './fleetSummaryService';
@Component({
selector: 'fleetSummary',
templateUrl: 'app/dashboard/features/fleet/fleetSummary/fleetSummaryTemplate.html',
directives: [ROUTER_DIRECTIVES]
})
export class FleetSummaryComponent implements OnInit, OnChanges {
fleetSummary: any[];
@Input() selectedTruckID: any;
errorMessage: any;
summary: any[];
// constructor to loop the products in product service file and disply in html
constructor(private _fleetSummaryService: FleetSummaryService){
}
// render something initially
ngOnInit(): void {
}
// render something on constant changes
ngOnChanges(): void{
console.log("data inside fleet summary: ", this.selectedTruckID.fleetId)
this._fleetSummaryService.getFleetSummary()
.subscribe(
fleetSummary => this.summary = fleetSummary,
error => this.errorMessage = <any>error)
console.log(" fleet summary: ", this.summary)
for (var i = 0; i < this.summary.length; i++) {
var summaryData = this.summary[i];
console.log(" fleet summary ID: ", summaryData.fleetId)
if (summaryData.fleetId == this.selectedTruckID.fleetId) {
this.fleetSummary = summaryData;
console.log(this.fleetSummary);
break;
}else {
this.fleetSummary = null;
}
}
}
}
ここに非同期メソッドがあります:
this._fleetSummaryService.getFleetSummary()
.subscribe(
fleetSummary => this.summary = fleetSummary,
error => this.errorMessage = <any>error)
この後、あなたはそれをここで反復しようとしています:
for (var i = 0; i < this.summary.length; i++) {
コードは、サブスクリプションからの応答が到着する前にforループに入ります。したがって、this.summary
は未定義になります。
応答を反復処理したい場合到着したとき次のように、コールバック内でforループを移動する必要があります。
this._fleetSummaryService.getFleetSummary()
.subscribe(
(fleetSummary) => {
this.summary = fleetSummary;
console.log(" fleet summary: ", this.summary);
for (var i = 0; i < this.summary.length; i++) {
var summaryData = this.summary[i];
console.log(" fleet summary ID: ", summaryData.fleetId);
if (summaryData.fleetId == this.selectedTruckID.fleetId) {
this.fleetSummary = summaryData;
console.log(this.fleetSummary);
break;
}else {
this.fleetSummary = null;
}
}
},
error => this.errorMessage = <any>error);