Angular不将JSON响应映射到嵌套接口

时间:2020-06-18 12:50:19

标签: json angular typescript

我的JSON响应(来自ASP.NET核心Web API)如下:

[
  {
    "pilot": {
      "firstName": "TEST",
      "lastName": "LAST",
      "assignedFlight": "O_FLIGHT"
    }
  },
  {
    "pilot": {
      "firstName": "First",
      "lastName": "Last",
      "assignedFlight": "M_FLIGHT"
    }
  }
]

我的TypeScript界面​​如下:

pilot.ts

export interface Pilot {
    firstName: string;
    lastName: string;
    assignedFlight: string;
}

commitment.ts

import { Pilot } from './pilot';

export interface Commitment {
    pilot: Pilot;
}

在我的 commitments.service.ts

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

  private commitmentsApiUrl = 'http://localhost:55012/commitments';

  constructor(private http: HttpClient) { }

  getCommitments(): Observable<Commitment[]> {
    return this.http.get<Commitment[]>(this.commitmentsApiUrl).pipe(tap(ev => console.log(ev)));
  }
}

最后,我在组件中订阅了可观察对象:

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

  commitments: Commitment[];

  constructor(private commitmentsService: CommitmentsService) { }

  ngOnInit(): void {
    this.commitmentsService.getCommitments().subscribe(commitments => this.commitments = commitments);
    console.log(this.commitments); /* Undefined here??? */
  }
}

在我生命中,我无法弄清楚为什么在涉及嵌套接口时未映射JSON。组件中的this.commitments显示undefined。我已经通过JSON验证程序/ linter运行了JSON,它表明它是有效的。我知道答案很简单,很容易被我忽略。有任何想法吗?谢谢!

2 个答案:

答案 0 :(得分:2)

界面看起来不错。 this.commitments是异步分配的。到您执行控制台日志时,变量this.commitments仍未定义。您需要在订阅中移动console.log()

this.commitmentsService.getCommitments().subscribe(
  commitments => {
    this.commitments = commitments;
    console.log(this.commitments);
  },
  error => {
    // always good practice to handle HTTP errors
  }
);

有关如何访问异步数据here的更多详细信息。

答案 1 :(得分:1)

除非您绝对必须在组件中包含this.commitments,否则不需要。这使事情变得更加复杂,请改用异步管道:

// component
@Component({
  selector: 'app-commitments',
  templateUrl: './commitments.component.html',
  styleUrls: ['./commitments.component.css']
})
export class CommitmentsComponent implements OnInit {
  commitments$ = this.commimentsService.getCommitments();
  constructor(private commitmentsService: CommitmentsService) { }
}

//template
<some-other-component [commitments]="commitments$ | async"></some-other-component>

“使事情变得更加复杂”是指您需要处理很多事情-管理订阅,确保从组件内部访问this.commitments是最新的。

我在一个应用程序中开发了一个应用程序,其中每个组件都会创建大量实例变量,这完全是出于您上面编写的模式的目的。它变得比您想象的要快得多。