简体   繁体   English

Angular 属性在“对象”类型上不存在

[英]Angular Property does not exist on type 'Object'

I'm having a few problems with Angular.我在使用 Angular 时遇到了一些问题。

I'm trying to iterate through a JSON Api but I'm receiving the message "Property does not exist on type 'Object'.我正在尝试遍历 JSON Api 但我收到消息“属性在类型'对象'上不存在。

Not exactly that, the error is "Property 'sprints' does not exist on type 'Project'"不完全是,错误是“'Project'类型上不存在属性'sprints'”

I have this HTML template :我有这个HTML 模板

<mat-toolbar>
    <span>{{ currentProject.title }}</span>
</mat-toolbar>
<div class="data-panel">
  <mat-card>
    <mat-toolbar style="border-radius: 4px 4px 0px 0px;">
              <span>Development</span>
          </mat-toolbar>
          <mat-card-content>
            <span>Access Code: {{ currentProject.accessCode }}</span>
            <div *ngFor="let sprint of currentProject.sprints">  <---- THIS IS WERE THE ERROR HAPPENS
              <span>{{ sprint }}</span>
            </div>
          </mat-card-content>
  </mat-card>
</div>

And my JSON :还有我的JSON

{
    "id": 1,
    "title": "App Komputer",
    "description": "Website dedicated to computer related products",
    "accessCode": "5128",
    "createdAt": "2022-01-13T21:19:11.000Z",
    "updatedAt": "2022-01-13T21:19:16.000Z",
    "sprints": [{
        "id": 1,
        "title": "Sprint 1",
        "releaseDate": "2022-01-20T21:37:13.000Z",
        "description": "Specs up to 01/22/2022",
        "createdAt": "2022-01-13T21:37:58.000Z",
        "updatedAt": "2021-12-13T01:46:36.000Z",
        "projectId": 1,
        "specifications": [{
            "id": 1,
            "title": "Add product button",
            "description": "New product button HTML",
            "duration": 10,
            "status": 1,
            "createdAt": "2021-12-23T01:46:36.000Z",
            "updatedAt": "2021-12-23T01:46:36.000Z",
            "sprintId": 1
        }]
    }]
}

Also, this is my Component :另外,这是我的组件

constructor(
    private projectService: ProjectService,
    private route: ActivatedRoute,
    private router: Router,
    private _titleService: Title
    ) { }

  ngOnInit(): void {
    if (!this.viewMode) {
      this.message = '';
      this.getProject(this.route.snapshot.params["id"]);
    }
  }

  getProject(id: string): void {
    this.projectService.get(id)
      .subscribe({
        next: (data) => {
          this.currentProject = data;
          console.log(data);
          this._titleService.setTitle(data.title+' · Scrumy');
        },
        error: (e) => console.error(e)
      });
  }

How can I fix this error?我该如何解决这个错误? I've tried many things but none worked.我尝试了很多东西,但没有一个奏效。

Thank you!谢谢!


EDIT 01/22/2022编辑 2022 年 1 月 22 日

For those who asked, here's the complete scheme of project-details-component.ts , where I get the function from:对于那些询问的人,这里是project-details-component.ts的完整方案,我从这里得到 function:

import { Component, Input, OnInit } from '@angular/core';
import { ProjectService } from 'src/app/services/project.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Project } from 'src/app/models/project.model';
import { Title } from "@angular/platform-browser";
import { Moment } from 'moment';
import { EChartsOption } from 'echarts';

@Component({
  selector: 'app-project-details',
  templateUrl: './project-details.component.html',
  styleUrls: ['./project-details.component.css']
})
export class ProjectDetailsComponent implements OnInit {

  @Input() viewMode = false;

  @Input() currentProject: Project = {
    title: '',
    description: '',
    accessCode: ''
  };
  
  message = '';

  constructor(
    private projectService: ProjectService,
    private route: ActivatedRoute,
    private router: Router,
    private _titleService: Title
    ) { }

  ngOnInit(): void {
    if (!this.viewMode) {
      this.message = '';
      this.getProject(this.route.snapshot.params["id"]);
    }
  }

  getProject(id: string): void {
    this.projectService.get(id)
      .subscribe({
        next: (data) => {
          this.currentProject = data;
          console.log(data);
          this._titleService.setTitle(data.title+' · Scrumy');
        },
        error: (e) => console.error(e)
      });
  }

}

This is the project.model.ts :这是项目。model.ts

export class Project {
  id?: any;
  title?: string;
  description?: string;
  accessCode?: string;
  createdAt?: Date;
  updatedAt?: Date;
}

Don't you also get errors for title and accessCode properties?你不会也得到titleaccessCode属性的错误吗? Because you are mixing synchronous code with asynchronous and that's usually causing the issue you are facing.因为您将同步代码与异步代码混合在一起,这通常会导致您面临的问题。

To explain, your template expects that the currentProject is immediately available, which is not true, because you load it from some service.解释一下,您的模板期望currentProject立即可用,这是不正确的,因为您从某个服务加载它。 And depending on how long will that take your template wants to draw data from currentProject but it was not yet initialized.并且取决于您的模板需要多长时间才能从currentProject中提取数据,但它尚未初始化。

If you don't want to rewrite your code to use async pipe, either put the whole block to *ngIf=",!currentProject", or add question marks before currentProject` properties.如果您不想重写代码以使用async pipe,请将整个块放入*ngIf=",!currentProject", or add question marks before

<span>Access Code: {{ currentProject?.accessCode }}</span>
<div *ngFor="let sprint of currentProject?.sprints">
  <span>{{ sprint }}</span>
</div>

Comparing your JSON data and Product interface, you have missed out sprints property in your model.比较您的 JSON 数据和Product界面,您错过了 model 中的sprints属性。

Via json2ts , your Product interface should be as below:通过json2ts ,您的Product界面应如下所示:

export interface RootObject {
    id: number;
    title: string;
    description: string;
    accessCode: string;
    createdAt: Date;
    updatedAt: Date;
    sprints: Sprint[];
}

export interface Sprint {
    id: number;
    title: string;
    releaseDate: Date;
    description: string;
    createdAt: Date;
    updatedAt: Date;
    projectId: number;
    specifications: Specification[];
}

export interface Specification {
    id: number;
    title: string;
    description: string;
    duration: number;
    status: number;
    createdAt: Date;
    updatedAt: Date;
    sprintId: number;
}

Another concern is the concern mentioned by @mat, as currentProject data is asynchronous.另一个问题是@mat 提到的问题,因为currentProject数据是异步的。 Either you have to initialize the value to currentProject :您必须将值初始化为currentProject

@Input() currentProject: Project = {
  title: '',
  description: '',
  accessCode: '',
  sprints: []
};

Or using Typescript optional chaining ( ?. ) to escape error when currentProject was null or undefined .或者,当currentProjectnullundefined时,使用Typescript 可选链接 ( ?. )来逃避错误。

@Input() currentProject: Project;
<mat-toolbar>
  <span>{{ currentProject?.title }}</span>
</mat-toolbar>
<div class="data-panel">
  <mat-card>
    <mat-toolbar style="border-radius: 4px 4px 0px 0px;">
      <span>Development</span>
    </mat-toolbar>
    <mat-card-content>
      <span>Access Code: {{ currentProject?.accessCode }}</span>
      <div *ngFor="let sprint of currentProject?.sprints">
        <span>{{ sprint | json }}</span>
      </div>
    </mat-card-content>
  </mat-card>
</div>

Sample Demo on StackBlitz StackBlitz 上的示例演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM