错误类型错误:无法读取未定义的属性(读取“companyForm”)

问题描述 投票:0回答:1

我正在尝试从后端的用户表中获取布尔值 isCompany 和字符串 companyName 和 nip 等数据,并将其设置为表单字段中的默认值。所有其他数据均已正确修补。只有这些有问题。

数据已正确获取并且存在于数据库中。问题是我收到此

create-order.component.html:14 ERROR TypeError: Cannot read properties of undefined (reading 'companyForm')
错误,并且这些字段在表单中保持为空。

这就是我在

form.service.ts
中初始化表单的方式:

  initCompanyForm(): FormGroup {
    return new FormGroup({
      companyName: new FormControl('', {}),
      nip: new FormControl('', {
        validators: [Validators.pattern(/^\d{10}$/)]
      })
    });
  }

这是

company-form.component.ts
:

export class CompanyFormComponent {
  companyForm: FormGroup;

  constructor(private formService: FormService) {
    this.companyForm = this.formService.initCompanyForm();
  }

  get controls() {
    return this.companyForm.controls as { [key: string]: FormControl };
  }

  getErrorMessage(control: FormControl): string {
    return this.formService.getErrorMessage(control);
  }
}

这个 Angular 组件

create-order.component
管理一个多步骤订单表单,其中包含客户、地址、交货、公司和其他信息的子组件。出现此问题的原因是,当 fetchUserProfile() 尝试修补其表单值时,CompanyFormComponent 未完全初始化,从而导致未定义的错误。即使使用 ngAfterViewInit,配置文件获取 (profileService.getUserProfile()) 的异步性质也会导致时间不匹配。我猜问题是配置文件数据在 CompanyFormComponent 准备好之前到达。

export class CreateOrderComponent implements OnInit, AfterViewInit {
  errorMsg: null | string = null;
  saveShipping = false;
  isAuthenticated = false;
  isCompany = false;

  @ViewChild(CustomerFormComponent) customerFormComp!: CustomerFormComponent;
  @ViewChild(AddressFormComponent) addressFormComp!: AddressFormComponent;
  @ViewChild(DeliveryFormComponent) deliveryFormComp!: DeliveryFormComponent;
  @ViewChild(CompanyFormComponent) companyFormComp!: CompanyFormComponent;
  @ViewChild(InfoFormComponent) infoFormComp!: InfoFormComponent;

  constructor(
    private location: Location,
    private router: Router,
    private ordersService: OrdersService,
    private profileService: ProfileService,
    private authService: AuthService
  ) {}

  ngOnInit(): void {
    const locationState = this.location.getState() as {
      summaryPrice: undefined | number;
      navigationId: number;
    };

    if (!locationState.summaryPrice) {
      this.router.navigate(['']);
    }

    this.checkIfUserIsLoggedIn();
  }

  ngAfterViewInit(): void {
    if (this.isAuthenticated) {
      this.fetchUserProfile();
    }
  }

  checkIfUserIsLoggedIn(): void {
    this.authService.isLoggedIn().subscribe({
      next: (response) => {
        this.isAuthenticated = response.message;
        if (this.isAuthenticated) {
          this.fetchUserProfile();
        }
      },
      error: (err) => {
        this.isAuthenticated = false;
        console.error('Error checking login status:', err);
      }
    });
  }

  fetchUserProfile(): void {
    this.profileService.getUserProfile().subscribe({
      next: (profile) => {
        console.log('User profile:', profile);

        this.customerFormComp.customerForm.patchValue({
          firstName: profile.firstName || '',
          lastName: profile.lastName || '',
          email: profile.email || ''
        });

        if (profile.phone) {
          this.customerFormComp.controls.phone.setValue(profile.phone);
        }

        this.addressFormComp.addressForm.patchValue({
          city: profile.city || '',
          street: profile.street || '',
          number: profile.number || '',
          postCode: profile.postCode || ''
        });

        if (profile.company) {
          this.isCompany = true;

          if (this.companyFormComp?.companyForm) { // this if omits the error, but doesn't solve the problem
            console.log('Patching company form with:', {
              companyName: profile.companyName,
              nip: profile.nip
            });
            this.companyFormComp.companyForm.enable();
            this.companyFormComp.companyForm.patchValue({
              companyName: profile.companyName || '',
              nip: profile.nip || ''
            });
          }
        } else {
          this.isCompany = false;
          if (this.companyFormComp?.companyForm) {
            this.companyFormComp.companyForm.reset();
            this.companyFormComp.companyForm.disable();
          }
        }
      },
      error: (err) => {
        this.errorMsg = 'Nie udało się załadować danych użytkownika';
        console.error('Error fetching user profile:', err);
      }
    });
  }

  onCompanyChange(): void {
    console.log('Checkbox changed:', this.isCompany);
    if (this.isCompany) {
      console.log('Enabling company fields...');
      this.companyFormComp.companyForm.enable();
    } else {
      console.log('Disabling and resetting company fields...');
      this.companyFormComp.companyForm.reset();
      this.companyFormComp.companyForm.disable();
    }
  }

  order(): void {
    if (
      this.customerFormComp.customerForm.valid &&
      this.addressFormComp.addressForm.valid &&
      this.deliveryFormComp.deliveryForm.valid &&
      (!this.isCompany || this.companyFormComp.companyForm.valid)
    ) {
      const orderData = {
        address: this.addressFormComp.addressForm.getRawValue(),
        deliver: this.deliveryFormComp.deliveryForm.getRawValue(),
        customerDetails: this.customerFormComp.customerForm.getRawValue(),
        isCompany: this.isCompany,
        companyName: this.isCompany
          ? this.companyFormComp.companyForm.get('companyName')?.value
          : null,
        nip: this.isCompany
          ? this.companyFormComp.companyForm.get('nip')?.value
          : null,
        info: this.infoFormComp.infoForm.get('info')?.value || null
      };

      console.log(
        'Order data being sent to backend:',
        JSON.stringify(orderData, null, 2)
      );

      this.ordersService.addOrder(orderData).subscribe({
        next: () => {
          if (this.saveShipping && this.isAuthenticated) {
            this.saveShippingDetails(orderData.address);
          }
        },
        error: (err) => {
          this.errorMsg = err;
          console.error('Order submission error:', err);
        }
      });
    } else {
      console.warn('Form is invalid');
    }
  }

所有表单组件都在

create-order.component
中。

This is the error I get when I don't have the if (this.companyFormComp?.companyForm)

This is the error I get when I uncheck and check the isCompany checkBox

angular typescript forms rxjs properties
1个回答
0
投票

我猜

onCompanyChange
方法会在视图子项可用之前触发。仅当
companyFormComp
视图子级存在时,您才可以更改触发重置的方法。

  onCompanyChange(): void {
    console.log('Checkbox changed:', this.isCompany);
    if(this.companyFormComp?.companyForm) {
      if (this.isCompany) {
        console.log('Enabling company fields...');
        this.companyFormComp.companyForm.enable();
      } else {
        console.log('Disabling and resetting company fields...');
        this.companyFormComp.companyForm.reset();
        this.companyFormComp.companyForm.disable();
      }
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.