Angular 无法识别对象的类型

时间:2021-06-16 09:32:26

标签: java angular typescript typechecking

我有一个带有 Java 后端的 Angular 项目。

以下是场景。

我在后端创建了一个 DTO 对象,并将其提交给前端。

    ...
    QuestionResponseDTO dto = new QuestionResponseDTO();
    dto.setStart(ZonedDateTime.now());
    dto.setEnd(ZonedDateTime.now());
    dto.setDuration("X seconds");
    dto.setResponse(new ActivityListResponseDTO(Arrays.asList("Cooking", "Eating")));
    return dto;
}

其中 ActivityListResponseDTO 只包含一个 List<String> activities。 另请注意,ActivityListResponseDTO 扩展了 QuestionResponseBodyDTO。

在前端,我将请求发送到后端,然后我收到返回的对象。 这就是对象的样子。

{"id":2,"responses":[{"id":0,"dto":{"start":"2021-06-16T09:08:28.142Z","end":"2021-06-16T09:08:28.142Z","duration":"X seconds",
"response":{
"activities":["Cooking","Eating"],
"typeName":"ActivityListResponseDTO",
"className":null},
"typeName":"QuestionResponseDTO",
"className":null}}]}

这意味着后端工作正常。

我之前提到的 java 类在 Frontend 中有其对应的类,名称完全相同。知道解析响应到底发生了什么。

当我收到物品时,我会检查:

//angular
if (dto instanceof QuestionResponseDTO) {
        console.log("this ran");
        const responseBody = ((<QuestionResponseDTO>dto).response);

        if(responseBody instanceof ActivityListResponseDTO) {
          console.log("this ran 2");
          // because backend only returns a string
          const arr = (<ActivityListResponseDTO>responseBody)
            .activities.map(s => ({stringContent: s}));
...

默认的 responseBody 在前端也有类型 QuestionResponseBodyDTO。 ActivityListResponseDTO 也在前端扩展了它,所以它应该可以工作。 但由于某种原因,程序没有进入内部 if 语句,并且 "this ran 2" 从未被记录。

是不是我做错了什么?

1 个答案:

答案 0 :(得分:0)

从 HTTP API 收到的响应将是一个简单的 JSON 对象。

要使其在前端正常工作,您必须将该对象映射到前端对应的类型。

您可以使用 json-object-mapper 库来实现这一点。

  1. 使用所有嵌套的对象类创建一个名为 QuestionResponseDTO 的 Typescript 类。我通常使用为我提供接口的 json2ts 来执行此操作,然后我将这些接口转换为 typescript 类。
  2. 使用 json-object-mapper 或使用您自己的类构造函数来初始化属性
  3. 在您的 HTTP 服务中,当您获得数据时,通过管道将该数据反序列化为打字稿对象。 http.get<QuestionResponseDTO>(url).pipe(map(data => ObjectMapper.deserialize(QuestionResponseDTO, data)));
  4. 完成此操作后,您应该能够在任何嵌套对象上正确使用 instanceof