ОШИБКА TypeError: Невозможно прочитать свойство undefined - PullRequest
0 голосов
/ 26 октября 2018

У меня есть приложение на Angular 6, пользователь может следить, нравится, не нравится и т.д. Я пытаюсь сохранить данные на сервере с помощью метода записи.

Когда пользователь нажимает, например, следовать, я получаю следующую ошибку:

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

}

Вот компонент ТС

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

Харви Призрак

Нью-Йорк США
      </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 голосов
/ 26 октября 2018

, как я вижу, вы не передали аргумент вашему методу followButtonClick() в html, поэтому переместите свою кнопку в цикле *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); 
}

, чтобы вы не передавали аргумент, ваш statusId равен undefined в followButtonClick(), поэтому он пытается получить this.status[undefined].followers++; и выдает ошибку, которая можетне найти недвижимость followers из undefined

0 голосов
/ 26 октября 2018

Даже если this.status - это массив, нет гарантии, что индекс состояния и его statusId будут одинаковыми.Таким образом, вы можете получить индекс, который не существует в вашем массиве status и, следовательно, неопределенная ошибка

Попробуйте изменить реализацию followButtonClick(statusId) следующим образом:

followButtonClick(statusId) {
  const statusToUpdate = this.status.filter(status => status.statusId === statusId)[0];
  statusToUpdate.followers++;
  this.persistStatus(statusToUpdate);
}
0 голосов
/ 26 октября 2018

Кажется, проблема в том, что ваш userService отправляет пустые данные, затем эти пустые данные загружаются в массив состояния. Этого не должно быть.

Вы можете справиться с этим в userService (желательно, чтобы код, размещенный на http://localhost:3000/statuses) Если у вас нет контроля со стороны сервера, вы можете исправить их ошибку при вызове this.userService.getStatuses(), чтобы проверить, является ли данные действительным объектом, а не пустым.

0 голосов
/ 26 октября 2018

Вы ничего не передаете в качестве параметра в HTML-части, тогда основываясь на той же функции, но с параметром, который вы продолжаете в TS-части.

Измените эту строку на:

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

PS: Предполагая, что он назван id, конечно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...