Angular Update表单填充输入字段但仍然在控制台中返回错误?

时间:2018-05-14 01:21:26

标签: javascript angular

我正在尝试在Angular中创建更新表单。我已经尝试了很多东西,但是我再一次对Angular不熟悉。这看起来很简单,我使用ngOnInit()方法获取数据(返回正确的数据)。用户数据显示在输入字段中,但随后出现错误。

这是我在控制台中收到的错误:

UpdateComponent.html:6 ERROR TypeError: Cannot read property 'firstName' of undefined
    at Object.eval [as updateDirectives] (UpdateComponent.html:6)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:11914)
    at checkAndUpdateView (core.js:11307)
    at callViewAction (core.js:11548)
    at execComponentViewsAction (core.js:11490)
    at checkAndUpdateView (core.js:11313)
    at callViewAction (core.js:11548)
    at execEmbeddedViewsAction (core.js:11511)
    at checkAndUpdateView (core.js:11308)
    at callViewAction (core.js:11548)

我的update.component.html文件:

<div>
<h2 class="page-header">Edit your Profile</h2>
<form (ngSubmit)="onUpdateSubmit(user)" novalidate>
  <div class="form-group">
    <label for="firstName">First Name</label>
    <input type="text" [(ngModel)]="user.firstName" name="firstName" class="form-control" id="firstName" placeholder="First Name">
  </div>
  <div class="form-group">
    <label for="lastName">Last Name</label>
    <input type="text" [(ngModel)]="user.lastName" name="lastName" class="form-control" id="lastName" placeholder="Last Name">
  </div>
  <div class="form-group">
    <label for="age">Age</label>
    <input type="number" [(ngModel)]="user.age" name="age" class="form-control" id="age" placeholder="Age" min="0" max="200">
  </div>
  <div class="form-group">
    <label for="favoriteFood">What is your Favorite Food?</label>
    <input type="text" [(ngModel)]="user.favoriteFood" name="favoriteFood" class="form-control" id="favoriteFood" placeholder="Favorite Food">
  </div>
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" [(ngModel)]="user.username" name="username" class="form-control" id="username" placeholder="Username">
  </div>
  <div class="form-group">
    <label for="exampleInputEmail1">Email address</label>
    <input type="email" [(ngModel)]="user.email" name="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
    <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
  </div>
  <div class="form-group">
    <label for="exampleInputPassword1">Password</label>
    <input type="password" [(ngModel)]="password" name="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
  </div>
  <button type="submit" class="btn btn-primary">Submit</button>
</form>
</div><div>
<h2 class="page-header">Edit your Profile</h2>
<form (ngSubmit)="onUpdateSubmit(user)" novalidate>
  <div class="form-group">
    <label for="firstName">First Name</label>
    <input type="text" [(ngModel)]="user.firstName" name="firstName" class="form-control" id="firstName" placeholder="First Name">
  </div>
  <div class="form-group">
    <label for="lastName">Last Name</label>
    <input type="text" [(ngModel)]="user.lastName" name="lastName" class="form-control" id="lastName" placeholder="Last Name">
  </div>
  <div class="form-group">
    <label for="age">Age</label>
    <input type="number" [(ngModel)]="user.age" name="age" class="form-control" id="age" placeholder="Age" min="0" max="200">
  </div>
  <div class="form-group">
    <label for="favoriteFood">What is your Favorite Food?</label>
    <input type="text" [(ngModel)]="user.favoriteFood" name="favoriteFood" class="form-control" id="favoriteFood" placeholder="Favorite Food">
  </div>
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" [(ngModel)]="user.username" name="username" class="form-control" id="username" placeholder="Username">
  </div>
  <div class="form-group">
    <label for="exampleInputEmail1">Email address</label>
    <input type="email" [(ngModel)]="user.email" name="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
    <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
  </div>
  <div class="form-group">
    <label for="exampleInputPassword1">Password</label>
    <input type="password" [(ngModel)]="password" name="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
  </div>
  <button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>

我的update.component.ts文件:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { ValidateService } from '../../services/validate.service';
import { Router } from "@angular/router";
import { FlashMessagesService } from 'angular2-flash-messages';

@Component({
  selector: 'app-update',
  templateUrl: './update.component.html',
  styleUrls: ['./update.component.css']
})
export class UpdateComponent implements OnInit {
  user: Object;

  constructor(
    private authService: AuthService,
    private validateService: ValidateService,
    private router: Router,
    private _flashMessagesService: FlashMessagesService
  ) { }

  ngOnInit() {
    this.authService.getProfile().subscribe(profile => {
      this.user = profile.user;
    },
    err => {
      console.log(err);
      return false;
    });
  }

  onUpdateSubmit(user) {
    console.log("Component", user)
    // Required Fields
    if(!this.validateService.validateSignup(user)) {
      this._flashMessagesService.show("Please fill in all fields", {cssClass: "alert-danger", timeout: 3000});
      return false;
    }

    // Validate Email
    if(!this.validateService.validateEmail(user.email)) {
      this._flashMessagesService.show("Please use valid email", {cssClass: "alert-danger", timeout: 3000});
      return false;
    }

    // Update user
    this.authService.updateUser(user).subscribe(data => {
      if(data.success) {
        this._flashMessagesService.show("Update Success!", {cssClass: "alert-success", timeout: 3000});
        this.router.navigate(["/profile"]);
      } else {
        this._flashMessagesService.show("Something went wrong", {cssClass: "alert-danger", timeout: 3000});
        this.router.navigate(["/update"]);
      }
    });
  }

}

4 个答案:

答案 0 :(得分:1)

这是因为用户数据中没有返回firstName。也许它是未定义的。避免这个问题。

您最好:1。检查ngOnInit()中的用户数据是否已返回。 2.初始用户数据。 e,g:user = { firstName: '' }; 3.检查从服务

获取用户数据时是否存在延迟

答案 1 :(得分:0)

您的表单中有双向绑定,那么为什么需要在表单提交时传递用户。尝试使用如下

   <form (ngSubmit)="onUpdateSubmit()" novalidate>
    .
    .
    .

并使用

  onUpdateSubmit() {
    console.log("Component", this.user);
    .
    .
    .
 }

答案 2 :(得分:0)

您的错误消息很明确。您的用户在ngOnInit上通过api调用填充,但是在加载html后可能会返回响应。在加载时,您的DOM期望用户可用,但在您的情况下未定义。你可以通过几种方法解决这个问题。首先,按照通常的标准,在构造函数中定义您的用户,如下所示。

constructor(
    private authService: AuthService,
    private validateService: ValidateService,
    private router: Router,
    private _flashMessagesService: FlashMessagesService
  ) { 

   this.user = <Object>{};
}

现在您的用户未定义,即使user.name可能是未定义的,也会是短暂的,并且不会抛出错误。第二个选项是,更新您的update.component.html,仅在用户可用或未定义时加载您的DOM。为此,请在第一个div中添加* ngIf

<div *ngIf="user">
<h2 class="page-header">Edit your Profile</h2>
<form (ngSubmit)="onUpdateSubmit(user)" novalidate>
........
.........
</form
</div>

从上面开始,当用户未定义时,您的表单将不会被加载,因此避免了对user.name的需求。

答案 3 :(得分:0)

这是因为用户数据中没有定义firstName。这是因为在您加载页面时,您的user对象未初始化。如果在this.user中没有为ngOnInit分配对象,则会返回异常。 您可以通过两种方式解决此问题。 一种方法是在开始时初始化this.user对象。如果在ngOnInit中没有为用户对象分配对象,它将返回一个空白表单,但它不会返回异常。您可以通过在定义对象时或在构造函数中初始化user对象来实现。

定义对象时

user={}

或构造函数

this.user={}

第二种方法是,如果您只想在有数据的情况下显示表单,只有在*ngIf对象中有数据时才能使用user显示表单。

<div *ngIf="user">
<h2 class="page-header">Edit your Profile</h2>
<form (ngSubmit)="onUpdateSubmit(user)" novalidate>
........
.........
</form
</div>