错误TypeError:无法读取未定义的属性

时间:2018-10-26 12:45:43

标签: javascript angular html5 typescript angular6

我在Angular 6中有应用,用户可以关注,喜欢,不喜欢等。我正在尝试通过post方法将数据保存到服务器。

当用户单击“ eg”(跟随)时,出现以下错误:

UserProfileComponent.html:27 ERROR TypeError: Cannot read property 'followers' of undefined
    at UserProfileComponent.push../src/app/user-profile/user-profile.component.ts.UserProfileComponent.followButtonClick (user-profile.component.ts:46)
    at Object.eval [as handleEvent] (UserProfileComponent.html:27)
    at handleEvent (core.js:19324)
    at callWithDebugContext (core.js:20418)
    at Object.debugHandleEvent [as handleEvent] (core.js:20121)
    at dispatchEvent (core.js:16773)
    at core.js:17220
    at HTMLButtonElement.<anonymous> (platform-browser.js:988)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:13842)

这是服务器中的json文件:

{
  "statuses": [{
    "id": 1,
    "statusId": 2,
    "likes": 121,
    "following": 723,
    "followers": 4433
  }]
}

这是我提供的服务:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Status } from '../model/statuses.model';
import { Comment } from '../model/comments.model';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  status: Status[];
  constructor(private http: HttpClient) { }
  statusUrl = 'http://localhost:3000/statuses';
  commentsUrl = 'http://localhost:3000/comments';

  getStatuses() {
    return this.http.get<Status[]>(this.statusUrl);
  }

  addStatus(status: Status) {
   return this.http.patch(this.statusUrl, status);
  }

  addComments(comment: Comment) {
    return this.http.post(this.commentsUrl, comment);
  }

}

这是ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { UserService } from '../service/user.service';
import { Status } from '../model/statuses.model';
import { Comment } from '../model/comments.model';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-user-profile',
  templateUrl: './user-profile.component.html',
  styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent implements OnInit {
  status: Status[];
  comment: Comment[];
  numberOflikes = 121;
  numberOffollowing = 723;
  numberOffollowers = 4433;

  constructor(
    private formBuilder: FormBuilder,
    private http: HttpClient,
    private userService: UserService
  ) {}

  addForm: FormGroup;

  ngOnInit() {
    this.addForm = this.formBuilder.group({
      id: [],
      name: ['', Validators.required],
      city: ['', Validators.required],
      description: ['', Validators.required],
    });

    this.userService.getStatuses()
      .subscribe(data => {
        this.status = data;
        console.log(data);
      });
  }

  addComments() {
    this.userService.addComments(this.addForm.value)
      .subscribe(data => {
        this.comment.push(this.addForm.value);
      });
  }

  followButtonClick(statusId) {
    this.status[statusId].followers++;
    this.persistStatus(this.status[statusId]);
  }

  persistStatus(status) {
    this.userService.addStatus(status);
  }

}

这是html

              

Harvey Spectre

              美国纽约             
      </div>
      <ul class="profile_card-bottom" *ngFor="let stat of status">
        <li class="likes">
          <span class="assets-count">{{stat.followers}}</span>
          <span class="assets-title">Likes</span>
        </li>
        </ul>
</div>

这里是状​​态的榜样

export class Status {
    id: number;
    statusId: number;
    like: number;
    following: number;
    followers: number;
}

我的代码在做什么错了?

4 个答案:

答案 0 :(得分:1)

我看到您没有将参数传递给html中的followButtonClick()方法,因此请在*ngFor循环中移动按钮并传递stat.id 如@selemmn

<h1>
 Harvey Specter
 <span class="heart reaction">
  <i class="fa fa-heart heart" aria-hidden="true"(click)="followButtonClick(stat.id)"></i>
 </span>
</h1>

并将您的followButtonClick()方法更改为此

followButtonClick(statusId) { 
 const statusToUpdate = this.status.filter(status => status.id === statusId)[0]; 
 statusToUpdate.followers++; 
 this.persistStatus(statusToUpdate); 
}

因此,由于您没有传递参数,因此statusIdundefined中是followButtonClick(),因此它试图获取this.status[undefined].followers++;并抛出找不到属性{{ 1}},共followers

答案 1 :(得分:0)

您不会在HTML部分中传递任何参数作为参数,而是基于相同的函数,但会在TS部分中传递参数。

this line更改为:

<button class="btn-follow" (click)="followButtonClick(stat.id)">Follow</button>

PS:当然,假设它的名称为id

答案 2 :(得分:0)

即使this.status是一个数组,也不保证状态的索引与statusId相同。因此,您可能会得到status数组中不存在的索引,从而导致未定义的错误

尝试像这样更改followButtonClick(statusId)的实现:

followButtonClick(statusId) {
  const statusToUpdate = this.status.filter(status => status.statusId === statusId)[0];
  statusToUpdate.followers++;
  this.persistStatus(statusToUpdate);
}

答案 3 :(得分:0)

问题似乎是您的userService正在发送空数据,然后将此空数据加载到状态数组中。这不应该发生。

您可以在userService中处理它(最好使用http://localhost:3000/statuses中托管的代码) 如果您无法控制服务器端,则可以在调用this.userService.getStatuses()来检查数据是否为有效对象而不是空对象时解决他们的错误。