angular
“Error: Uncaught (in promise): TypeError: Cannot read property 'length' of undefined”
Could anyone help with the error "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)" I am trying to get the values of an inner array from a json file to a variable that I have created. My json file is in the following format. JSON filename: file.json { "A":[ { "id": "123", "title": "title of A", "type": "asf", "B": [ { "id": "1", "title": "title1" }, { "id": "2", "title": "title2" } ] ] } I have created couple of models to store the values A.model.ts import {B} from './b.model'; export interface A { type?; id?; title?; b?: B[]; } B.model.ts export interface B { id?; title?; } My Service that returns the json has the following 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; }); } In the component.ts I have written the following code. <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; } } Can anyone help me telling what mistake I am doing? Or is there a way to get the 'B' array values. Thanks in advance.
The issue is that this.someService.get is asynchronous and you are trying to access the result of it as if it was synchronous: 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 The fix is to use this.aArray in the callback of the asynchronous method: 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 });
This res.json().showList is wrong. json returns a promise. A promise does not have a showList member. Fix toPromise() .then(res => res.json()) .then(A => { return A.showList; }); More An assertions should not be considered without caution.
Related Links
Angular 2 Passing parameters to the template through #Input() [closed]
All declarations of 'size' , 'prototype' must have identical modifiers
Accessing the Device Camera without getUserMedia [closed]
Template Error on ngFor and using pipe with parameter
Angular 2: Validators.compose() vs [] [duplicate]
angular 2 -spring boot
VelocityJS in a TypeScript project throws '../node_modules/#types/velocity-animate/index.d.ts is not a module'
How to resubscribe to an observable?
Angular material 2 dynamic button toggle group form control accessor
Debug Tests in NG Test
Angular 2. Doubled custom tags
Integration Stripe Elements with angular 2
How to format phone number while typing in angular 2?
Angular: Wrap providers in a module?
Angular - getting the handle to the ng-content component in the parent
How to use ng.material.MdDialog in ES5?