Перебираем массив объектов Angular 2


У меня есть массив объектов, полученных в служебном файле из файла json. Когда я подписываюсь на него в компоненте и пытаюсь повторить его, я получаю следующую ошибку:

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

    }

}
1 5

1 ответ:

У вас есть асинхронный метод здесь:

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