You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 11中ngOnInit()无法获取接口返回的Properties属性值问题

问题根因

HTTP请求属于异步操作,你在constructor中发起的接口请求不会阻塞后续代码执行,ngOnInit生命周期触发时,接口还没有返回数据,this.leave还未完成赋值,此时访问它的属性自然会抛出undefined错误。

解决步骤

1. 调整请求逻辑,数据返回后更新表单

将表单赋值操作放到接口请求的订阅回调中,确保拿到数据后再操作对应字段,参考修改后的组件代码:

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup} from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { AuthenticationService } from 'src/app/authentication.service';
import { Leave } from '../interfaces/leave';
import { LeaveService } from '../services/leave.service';

@Component({
  selector: 'app-add-edit-leave',
  templateUrl: './add-edit-leave.component.html',
  styleUrls: ['./add-edit-leave.component.css']
})
export class AddEditLeaveComponent implements OnInit {

 form: FormGroup;
 currentDate = new Date();
 minDate: Date;
 maxDate: Date;
 selectedFile: File = null;
 url : any;
 leave :Leave;
  
 constructor(
  private fb: FormBuilder, 
  private http: HttpClient,
  private leaveService : LeaveService,
  private route : ActivatedRoute,
  private authenticationService: AuthenticationService
 ) {
    const currentYear = new Date().getFullYear();
    this.minDate = new Date(currentYear - 20, 0, 1);
    this.maxDate = new Date(currentYear + 1, 11, 31);
 }
   
  ngOnInit() {
    // 先完成表单初始化
    this.form = this.fb.group({
      currentDate: new FormControl(this.currentDate.toISOString().split("T")[0]),
      joiningDate:[''],
      fromDate:[''],
      tillDate:[''],
      leaveType:[''],
      duration:[''],
      reason:[''],
      filePath:['']
    });
    // 发起接口请求,拿到数据后更新表单和leave实例
    this.leaveService.applyLeaveGet(this.authenticationService.getUserId())
      .subscribe(data => {
        this.leave = data;
        // 把接口返回的字段更新到响应式表单中
        this.form.patchValue({
          joiningDate: data.joiningDate
          // 其余需要回显的字段都可以在这里补充赋值
        })
      });
  }

  onSelectFile(event: any) {
    this.selectedFile = <File>event.target.files[0];
    if (event.target.files && event.target.files[0]) {
            var reader = new FileReader();
            reader.onload = (event: any) => {
                this.url = event.target.result;
            }
            reader.readAsDataURL(event.target.files[0]);
        }
        else
        {
          this.url = "";
        }
  }
  
  onSubmit(){
    var userId = this.authenticationService.getUserId();
    const formData = new FormData();
    formData.append('userId', userId);
    // 注意此处原代码所有字段都取了this.form.value.fullName属于笔误,需要替换为对应表单字段取值
    formData.append('currentDate', this.form.value.currentDate);
    formData.append('joiningDate', this.form.value.joiningDate);
    formData.append('fromDate', this.form.value.fromDate);
    formData.append('tillDate', this.form.value.tillDate);
    formData.append('leaveType', this.form.value.leaveType);
    formData.append('duration', this.form.value.duration);
    formData.append('reason', this.form.value.reason);
    formData.append('balanceAnnualLeave', this.leave.balanceAnnualLeave);
    formData.append('balanceSickLeave', this.leave.balanceSickLeave);
    formData.append('File', this.selectedFile);
  }
}

2. 修复模板渲染报错

HTML模板中直接访问leave的属性会在数据返回前抛出错误,有两种修复方式:

  • 方案一:使用可选链操作符
<li>
  annualLeaveBalacne: <span>{{leave?.balanceAnnualLeave}}</span> <br>
</li>
<li>
  sickLeaveBalance: <span>{{leave?.balanceSickLeave}}</span>
</li>
  • 方案二:增加ngIf判断,只有leave存在时才渲染对应模块
<div class="col-md-6" *ngIf="leave">
  <mat-label>Leave Balacne</mat-label><br>
  <ul>
    <li>
      annualLeaveBalacne: <span>{{leave.balanceAnnualLeave}}</span> <br>
    </li>
    <li>
      sickLeaveBalance: <span>{{leave.balanceSickLeave}}</span>
    </li>
  </ul>
</div>

内容的提问来源于stack exchange,提问作者StillLearning

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:54:04