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

Angular中已填充的Contract对象访问字段返回undefined问题求助

问题根因

this.contractService.getContract()是基于RxJS的异步请求,调用subscribe()后不会阻塞后续代码执行。你调用GetContract()后接口还没返回结果,就直接执行了后续访问this.contract的逻辑,此时this.contract还没被赋值,所以报undefined。你调试时能看到赋值是因为接口返回后才触发赋值操作,晚于你访问字段的时机。


修复方案

方案1:将依赖contract的逻辑移入异步回调

把后续取client的逻辑放到接口返回成功的回调中,保证访问this.contract时已经完成赋值,修改后代码如下:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Client } from '../../models/client';
import { Contract } from '../../models/Contract';
import { ClientService } from '../../services/client.service';
import { ContractService } from '../../services/contract.service';

@Component({
  selector: 'app-contract-customer',
  templateUrl: './contract-customer.component.html',
  styleUrls: ['./contract-customer.component.css']
})
export class ContractCustomerComponent implements OnInit {
  public contractNumber: string;
  public client: Client;
  public contract: Contract;

  constructor(private route: ActivatedRoute, private clientService: ClientService, private contractService: ContractService) { }

  ngOnInit():void  {
    // 更推荐用ActivatedRoute取路由参数,不需要手动拆分url
    // this.contractNumber = this.route.snapshot.paramMap.get('你定义的路由参数名');
    const url = window.location.href;
    var parts = url.split('/', 6);
    this.contractNumber = parts[4];
    console.log("Contract Id form url : " + this.contractNumber);
    this.GetContractClient();
  }

  GetContract(id: string) {
    this.contractService.getContract(Number(id)).subscribe(result => {
      this.contract = result;
      // 接口返回后再执行依赖contract的逻辑
      console.log("test id contract client" + this.contract.contractId);
      this.GetClient();
    }, error => {
      console.log(error)
    });
  }

  GetClient() {
    this.clientService.getClient(this.contract.contractId).subscribe(result => {
      this.client = result;
    }, error => {
      console.log('something wrong here!!!')
      console.log(error)
    });
  }

  GetContractClient() {
    this.GetContract(this.contractNumber);
  }
}

方案2:使用RxJS操作符链式调用

如果想让逻辑更清晰可维护,可以让GetContract返回Observable,用switchMap操作符串联两个请求:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { switchMap } from 'rxjs/operators';
import { Client } from '../../models/client';
import { Contract } from '../../models/Contract';
import { ClientService } from '../../services/client.service';
import { ContractService } from '../../services/contract.service';

@Component({
  selector: 'app-contract-customer',
  templateUrl: './contract-customer.component.html',
  styleUrls: ['./contract-customer.component.css']
})
export class ContractCustomerComponent implements OnInit {
  public contractNumber: string;
  public client: Client;
  public contract: Contract;

  constructor(private route: ActivatedRoute, private clientService: ClientService, private contractService: ContractService) { }

  ngOnInit():void  {
    const url = window.location.href;
    var parts = url.split('/', 6);
    this.contractNumber = parts[4];
    console.log("Contract Id form url : " + this.contractNumber);
    this.GetContractClient();
  }

  GetContract(id: string) {
    return this.contractService.getContract(Number(id));
  }

  GetContractClient() {
    this.GetContract(this.contractNumber).pipe(
      switchMap(contract => {
        this.contract = contract;
        console.log("test id contract client" + this.contract.contractId);
        return this.clientService.getClient(contract.contractId);
      })
    ).subscribe(result => {
      this.client = result;
    }, error => {
      console.log(error);
    });
  }
}

内容的提问来源于stack exchange,提问作者J.C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:15:00