【问题标题】:Angular - Property 'results' does not exist on type 'ICandidate'.ngtAngular - 类型“ICandidate”.ngt 上不存在属性“结果”
【发布时间】:2021-07-16 13:45:38
【问题描述】:

我有一个使用 Angular-12 的代码。如下图:

界面:

export interface ICandidate {
  id: number;
  first_name: string;
  other_name: string;
  last_name : string;
  email: string;
  gender : string;
  user_photo: any;
  marital_status: string;
  dob : Date;
  address : string;
  cv_file: any;
  achievement: IAchievement[];
  certificate: ICertificate[];
  education: IEducation[];
  experience: IExperience[];
  skills: ISkill[];
}

candidate.service:

import { ICandidate, IAchievement, ICertificate, IEducation, IExperience, ISkill } from '../models/candidate.model';

@Injectable({
  providedIn: 'root'
})
export class CandidateService {

  constructor(
    private http: HttpClient,
    private token: TokenService,
    private api: ApiService
  ) { }

  private candidateDetails!: ICandidate;

  getCandidateDetails(): ICandidate {
    return this.candidateDetails;
  }

  setCandidateDetails(candidateDetails: ICandidate): void {
    this.candidateDetails = candidateDetails;
  }

  getCandidateProfile(): Observable<ICandidate> {
    let headers = new HttpHeaders();
    headers = headers.set('Authorization', this.token.get());
    const url: string = this.api.baseURL + 'display';
    return this.http.get<ICandidate>(url, { headers });
  }
}

组件:

import { Component, OnInit } from '@angular/core';
import { CandidateService } from 'src/app/features/driver/services/candidate.service';
import { ICandidate } from 'src/app/features/driver/models/candidate.model';
import { AppState } from 'src/app/store/reducers';

@Component({
  selector: 'app-profile-list',
  templateUrl: './profile-list.component.html',
  styleUrls: ['./profile-list.component.scss']
})
export class ProfileListComponent implements OnInit {

  public loggedIn!: boolean;

  candidateDetails!: ICandidate;

  constructor(
    private store: Store<fromStore.AppState>,
    private router: Router,
    private auth: AuthService,
    private token: TokenService,
    private api : ApiService,
    private candidateService: CandidateService,
    ) {
    }

  ngOnInit(): void {

    this.candidateService.getCandidateProfile().subscribe(
      (response) => {
        console.log(response);
        this.candidateDetails = response;
        console.log(this.candidateDetails);
        this.candidateService.setCandidateDetails(this.candidateDetails);
      });
  }
}

当我做 console.log(response);在组件中,我得到了:

{
  "message": "Profile Successfully Retrieved.",
  "error": false,
  "code": 200,
  "results": {
    "profile": {
        "id": 2,
        "user_type": "Teacher",
        "created_at": "2021-07-07T07:19:13.000000Z",
        "updated_at": "2021-07-15T09:57:48.000000Z",
        "deleted_at": null,
        "last_login_at": "2021-07-15T09:57:48.000000Z",
        "detail": {
            "id": 1,
            "user_id": 2,
            "first_name": "Lamptey",
            "last_name": "Akwetey",
            "other_name": null,
            "email": "lamptey@yahoo.com",
            "gender": null,
            "user_photo": null,
            "marital_status": null,
            "dob": null,
            "address": null,
            "cv_file": null,
            "summary": null,
            "created_at": "2021-07-07T07:19:13.000000Z",
            "updated_at": null
        },
        "educations": [],
        "experiences": [],
        "achievements": [],
        "certificates": [],
        "skills": [],
        "employees": []
    }
}

profile 和 detail 具有单一数据。

现在我想显示个人资料、详细信息、教育和经历

{{ CandidateDetails.results.profile.user_type }}

给出这个错误:

类型“ICandidate”.ngt 上不存在属性“结果”

同样

{{ CandidateDetails.results.profile.detail.first_name }}

我该如何解决这个问题?

谢谢

【问题讨论】:

  • return this.http.get(url, { headers }).pipe(map(response => response.results.profile))
  • 正如@MikeOne 在我的回答中提到的,响应似乎与定义的接口不匹配。例如。界面中没有results 属性。修复后,您可以使用安全导航运算符:{{ candidateDetails?.results?.profile?.user_type }} 在尝试访问它的属性之前检查变量是否已定义。或者在任何属性未定义时执行{{ candidateDetails.results.profile.user_type || '-' }} 以显示其他内容(如-)。

标签: angular


【解决方案1】:

根据您提供的 JSON 结果和 Candidate.service.ts 中的 getCandidateProfile,您不能将其转换为 ICandidate,因为 JSON 结果与 ICandidate 模板不匹配。相反,ICandidate 是 JSON 的一小部分

您的界面应如下所示:

response.model.ts

export interface IResponse<T> {
  message: string;
  error: boolean,
  code: number,
  results: T;
}

candidate.model.ts

export interface IProfile {
  profile: ICandidate;
}

export interface ICandidate {
  id: number;
  user_type: string;
  created_at: string;
  updated_at: string;
  deleted_at: string;
  last_login_at: string;
  detail: ICandidateDetail;
  achievement: IAchievement[];
  certificate: ICertificate[];
  education: IEducation[];
  experience: IExperience[];
  skills: ISkill[];
}

export interface ICandidateDetail {
  id: number;
  first_name: string;
  other_name: string;
  last_name: string;
  email: string;
  gender: string;
  user_photo: any;
  marital_status: string;
  dob: Date;
  address: string;
  cv_file: any;
}

同时,我通过添加detail: ICandidateDetail 来更正您的ICandidate,其中ICandidateDetails 包含first_namelast_name 等属性以匹配您的JSON 模板。

candidate.service.ts

getCandidateProfile(): Observable<IResponse<IProfile>> {
  let headers = new HttpHeaders();
  headers = headers.set('Authorization', this.token.get());
  const url: string = this.api.baseURL + 'display';
  return this.http.get<IResponse<IProfile>>(url, { headers });
}

您也可以查看变量命名和类型,例如candidatecandidateDetail,以避免混淆。

profile-list.component.ts

export class ProfileListComponent implements OnInit {

  ...

  candidate!: ICandidate;
  candidateDetail!: ICandidateDetail;

  ...

  ngOnInit(): void {

    this.candidateService.getCandidateProfile().subscribe(
      (response: IResponse<IProfile>) => {
        console.log(response);
        this.candidate = response.results.profile;
        this.candidateDetail = response.results.profile.detail;
        this.candidateService.setCandidateDetails(this.candidate);
      });
  }
}

Sample solution on StackBlitz

【讨论】:

    【解决方案2】:

    响应是 ICandidate 类型,正如您在 Candidate.service 文件中所写:getCandidateProfile(): Observable&lt;ICandidate&gt; 并且您将整个响应分配给 CandidateDetails,就像您在此处所做的那样:this.candidateDetails = response;

    您的 ICandidate 接口具有以下属性:

      id: number;
      first_name: string;
      other_name: string;
      last_name : string;
      email: string;
      gender : string;
      user_photo: any;
      marital_status: string;
      dob : Date;
      address : string;
      cv_file: any;
      achievement: IAchievement[];
      certificate: ICertificate[];
      education: IEducation[];
      experience: IExperience[];
      skills: ISkill[];
    

    您收到该错误是因为您的响应与 ICandidate 接口的属性不同。

    您的回复中还有一个额外的“详细信息”参数。您应该将后端设置为以与您在 ICandidate 接口中配置的方式相同的方式返回数据,并且当属性相同且名称相同时,您就可以了。

    起初我以为“detail”参数包含了ICandidate中定义的所有参数,但后来发现它们并不相同,例如缺少这些参数

     "educations": [],
     "experiences": [],
     "achievements": [],
     "certificates": [],
     "skills": [],
    

    因此,第一步是在“详细信息”中放入 ICandidate 接口所需的所有数据,然后您可以在响应中像这样设置数据: this.candidateDetails = response.results.profile.details.

    【讨论】:

    • 我把这个放在组件响应中:this.candidateDetails = response.results.profile.details;但出现此错误:错误 TS2339:“ICandidate”类型上不存在属性“结果”。
    猜你喜欢
    • 2018-04-30
    • 2018-01-23
    • 2018-07-12
    • 2018-05-01
    • 1970-01-01
    • 2022-07-23
    • 2023-03-18
    • 2021-04-02
    • 2016-08-19
    相关资源
    最近更新 更多