Duong Nhat
Duong Nhat

Reputation: 1

Angular: Cannot read property 'data' of undefined

HomeComponent.html:16 ERROR TypeError: Cannot read property 'data' of undefined
    at Object.eval [as updateDirectives] (HomeComponent.html:16)
    at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13067)
    at checkAndUpdateView (core.es5.js:12251)
    at callViewAction (core.es5.js:12599)
    at execComponentViewsAction (core.es5.js:12531)
    at checkAndUpdateView (core.es5.js:12257)
    at callViewAction (core.es5.js:12599)
    at execEmbeddedViewsAction (core.es5.js:12557)
    at checkAndUpdateView (core.es5.js:12252)
    at callViewAction (core.es5.js:12599)
View_HomeComponent_0 @ HomeComponent.html:16
proxyClass @ compiler.es5.js:14985
DebugContext_.logError @ core.es5.js:13407
ErrorHandler.handleError @ core.es5.js:1080
(anonymous) @ core.es5.js:4819
ZoneDelegate.invoke @ zone.js:388
Zone.run @ zone.js:138
NgZone.runOutsideAngular @ core.es5.js:3844
ApplicationRef_.tick @ core.es5.js:4819
(anonymous) @ core.es5.js:4684
ZoneDelegate.invoke @ zone.js:388
onInvoke @ core.es5.js:3890
ZoneDelegate.invoke @ zone.js:387
Zone.run @ zone.js:138
NgZone.run @ core.es5.js:3821
next @ core.es5.js:4684
schedulerFn @ core.es5.js:3635
SafeSubscriber.__tryOrUnsub @ Subscriber.js:240
SafeSubscriber.next @ Subscriber.js:187
Subscriber._next @ Subscriber.js:128
Subscriber.next @ Subscriber.js:92
Subject.next @ Subject.js:56
EventEmitter.emit @ core.es5.js:3621
checkStable @ core.es5.js:3855
onHasTask @ core.es5.js:3903
ZoneDelegate.hasTask @ zone.js:441
ZoneDelegate._updateTaskCount @ zone.js:461
Zone._updateTaskCount @ zone.js:285
Zone.runTask @ zone.js:205
drainMicroTaskQueue @ zone.js:595
Promise resolved (async)
scheduleMicroTask @ zone.js:578
ZoneDelegate.scheduleTask @ zone.js:410
Zone.scheduleTask @ zone.js:232
Zone.scheduleMicroTask @ zone.js:252
scheduleResolveOrReject @ zone.js:856
ZoneAwarePromise.then @ zone.js:946
PlatformRef_._bootstrapModuleWithZone @ core.es5.js:4537
PlatformRef_.bootstrapModule @ core.es5.js:4522
(anonymous) @ main.ts:11
../../../../../src/main.ts @ main.bundle.js:559
__webpack_require__ @ inline.bundle.js:55
0 @ main.bundle.js:574
__webpack_require__ @ inline.bundle.js:55
webpackJsonpCallback @ inline.bundle.js:26
(anonymous) @ main.bundle.js:1
HomeComponent.html:16 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 37, nodeDef: {…}, elDef: {…}, elView: {…}}

Here's my home.component.ts

import { Component, OnInit } from '@angular/core';
import { AppService } from '../core/app-api.service';
import { Subscription } from 'rxjs';
import { Router, ActivatedRoute } from '@angular/router';
import { Headers } from '@angular/http';

import { LocationStrategy, PlatformLocation, Location } from '@angular/common';
import * as Chartist from 'chartist';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  public apps: any[];
  public _id: number;
  public subscription: Subscription;
  private headers = new Headers({ 'Content-Type': 'application/json' });

  constructor(public appService: AppService,
              private router: Router,
              private activatedRoute: ActivatedRoute, ) { }
  ngOnInit() {
    this.appService.getList().subscribe((response: any) => {
      this.apps = response;
    }, error => {
      console.log(error);
    });
    this.LoadData();
  }

  Remove(id: number) {
    let confirmResult = confirm("Are you sure to delete this app?");
    if (confirmResult) {
      this.appService.Delete(id).subscribe(response => {
        if (response) {
          alert("Deleted");
          this.LoadData();
        } else (error) => {
          console.log(error);
        }
      })
    }
  }
  LoadData() {
    this.appService.getAppById(this._id).subscribe(
      (data) => {
        this.apps = data;
      });
  }
  public stt: number = 1;

}

There's a home.component.html

<div class="main-content">
    <div class="container-fluid">
        <table class="table">
            <thead class="thead-light">
                <tr>
                    <th scope="col">id</th>
                    <th scope="col">Name</th>
                    <th scope="col">Icon</th>
                    <th scope="col">Detail</th>
                    <th scope="col">Created Date</th>
                    <th scope="col">Updated Date</th>
                    <th scope="col">Handle</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let app of apps.data|  paginate: { itemsPerPage: 5, currentPage: p}">
                    <th scope="row">{{app.id}}</th>
                    <td>{{app.name}}</td>
                    <td>
                        <img src="{{apps.url}}/{{app.icon}}"
                            alt="" width="60" height="60">
                    </td>
                    <td>
                        <a [routerLink]="['app-detail',app.id]" class="btn btn-primary">Read more...</a>
                    </td>
                    <td>{{app.created_at | date}}</td>
                    <td>{{app.updated_at | date}}</td>
                    <td class="td-actions ">
                        <a [routerLink]="['edit-app',app.id]" rel="tooltip" title="Edit App" style="margin-right:20px;" class="btn btn-success btn-simple btn-xs">
                            <i class="fa fa-2x fa-edit"></i>
                        </a>
                        <a (click)="Remove(app.id)" rel="tooltip" title="Remove" class="btn btn-danger btn-simple btn-xs">
                            <i class="fa fa-2x fa-times"></i>
                        </a>
                    </td>
                </tr>
            </tbody>

            <div id="paginate">
                <pagination-controls (pageChange)="p = $event"></pagination-controls>
            </div>
        </table>
    </div>
</div>

Here's my app.service.ts https://ibb.co/kfqJfc (I'm a newbie with angular 2,4 as well as have no experiences of uploading image so I randomly choose this one to show you guys then maybe you might think it's kind of a bug or viruses but it's actually not that way, I'm also grateful if anyone can recommend me another domain which people normally use)

Anyone with any ideas would be great for me, I'll provide you any files you want

Upvotes: 0

Views: 6160

Answers (3)

Rahul Ramesh
Rahul Ramesh

Reputation: 1

This is a similar problem to when you're using tables. Easy Fix: Add *ngIf to the parent. Example:

<table *ngIf = "items">
<tr *ngFor = "let item of items">
<td>item.something</td>
</tr>
</table>

Prevents Angular from looking for array before it's defined

Upvotes: 0

sonu singhal
sonu singhal

Reputation: 211

You are trying to access the data property of apps variable which is actually is not defined properly. Use "debugger;" statement in your typeScript code just after the line where you have set the value of apps variable it will allow you to debug your code into the chrome devTool and than you can check weather it is getting proper value or not.

this.appService.getList().subscribe((response: any) => {
          this.apps = response;
          debugger;
        }, error => {
          console.log(error);
        });

LoadData() {
        this.appService.getAppById(this._id).subscribe(
          (data) => {
            this.apps = data;
            debugger;
          });
      }

Upvotes: 1

kriss
kriss

Reputation: 1015

This is because you using apps in your template when it is not initialized in your ngOnInit. Add *ngIf in your template, so that html will be created when your apps is initialized

<tr *ngIf="apps" *ngFor="let app of apps.data|  paginate: { itemsPerPage: 5, currentPage: p}">

Upvotes: 1

Related Questions