在类型“Object”上不存在属性“json”。

47 浏览
0 Comments

在类型“Object”上不存在属性“json”。

我正在尝试使用Angular 2的HttpClient来通过REST获取数据。我正在遵循这里的Angular教程https://angular.io/tutorial/toh-pt6,在英雄和HTTP部分中,你会看到这段用于通过http获取英雄数据的代码片段。

getHeroes(): Promise {
  return this.http.get(this.heroesUrl)
         .toPromise()
         .then(response => response.json().data as Hero[])
         .catch(this.handleError);
}

下面是我在应用程序中编写的类似版本

fetch(startIndex: number, limit: number): Promise {
    let url = this.baseUrl + "&startIndex=" + startIndex + "&limit=" + limit;
    return this.http.get(url)
                .toPromise()
                .then(response => response.json().results as Order[])
                .catch(this.handleError);
}

我正在使用InteliJ Idea,调用response.json()时出现了红线,即使我尝试使用ng build构建也会出现错误。

类型“Object”上不存在属性“json”。

你可能会注意到,我使用的是json().results而不是json().data。这是因为根据教程,服务器返回了一个带有data字段的对象,但我的服务器返回了一个带有results字段的对象。如果你向下滚动一点,你会看到这一点。

注意服务器返回的数据形状。这个特定的内存Web API示例返回一个带有数据属性的对象。你的API可能返回其他内容。调整代码以匹配你的Web API。

为了解决这个问题,我尝试了如下的代码

(response: Response) => response.json().results as Order[]

当我这样做时,.json()方法被解析了,但是又出现了另一个错误

类型“Promise”上不存在属性“results”。

我尝试通过定义一个接口来解决这个问题

interface OrderResponse {
    orders: Order[];
}

并将get调用修改为

 .get(url)...

但是这也没有起作用。又出现了另一个错误

类型“OrderResponse”不能赋值给类型“Response”。

需要注意的一点是,教程中使用的是Angular HttpModule,但是在我的应用程序中,我使用的是新的Angular HttpClientModule,所以错误可能就出在这里。

我对Angular 2还不熟悉,这是我用它构建的第一个应用程序。如果上述代码在新的HttpClientModule中不再有效,我将非常感激如何使用新的HttpClientModule实现相同效果的任何帮助。

我在Property 'json' does not exist on type '{}'Property does not exist on type 'object'上找到了类似的问题,但那里的答案都没有帮助到我。

更新

正如评论中建议的那样,在新的HttpClientModule中没有.json()方法。我仍然需要在新模块中如何实现相同效果的帮助。根据指南,他们做了这样的事情

http.get('/api/items').subscribe(data => {
  // data现在是ItemsResponse类型的一个实例,所以你可以这样做:
  this.results = data.results;
});

我完全理解这个,但我的问题是,这段代码不是在组件中,而是在服务中,所以调用subscribe并将结果分配给一个实例字段并没有太多意义。

我希望我的服务返回一个包含在Promise中的Order数组。然后我的组件就可以这样调用

this.orderService.fetch(0, 10).then(orders => this.orders = orders)

我还考虑过在我的服务fetch方法中声明一个局部变量,这样我就可以做到

.subscribe(data => {
    this.orders = data.results;
}
// 并在get调用之外返回我的局部变量orders,如下所示
return Promise.resolve(orders)

但是对我来说这没有太多意义,因为.get()调用是异步的,方法可能在所有数据都被获取之前就返回了,orders数组可能为空。

更新

根据要求,这是handleError的代码

private handleError(error: any): Promise {
    console.log('An error occured ', error);
    return Promise.reject(error.message || error);
}

0
0 Comments

在新的HttpClient(Angular 4.3+)中,response对象默认为JSON格式,因此不再需要使用response.json().data。直接使用response即可。

解决方法是使用HttpClient替代原来的http模块,并将其注入到组件或服务中。然后在ngOnInit()方法中使用get()方法来发送GET请求,并通过subscribe()方法来订阅返回的响应。

在项目的app.module.ts中,不要忘记导入HttpClientModule,并在imports中包含它。

下面是一个修改自官方文档的示例代码:

import { HttpClient } from '@angular/common/http';
export class YourComponent implements OnInit {
  constructor(private http: HttpClient) {}
  
  ngOnInit(): void {
    this.http.get('https://api.github.com/users')
        .subscribe(response => console.log(response));
  }
}

在app.module.ts中:

import { HttpClientModule } from '@angular/common/http';
@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    ...
  ],
  ...
})

这是一个简单明了的例子,说明了问题的解决方法。如果每个人都能给出这样有帮助的答案,那就太好了。

0
0 Comments

问题原因:更新URL时,可能因为删除了尾部的"/api/"导致问题。这样做会导致根URL返回HTML,而不是预期的JSON数据。

解决方法:检查API的URL,确保尾部有"/api/"。添加缺失的"/api/"即可解决问题。

0
0 Comments

在上述内容中,出现了(Property 'json' does not exist on type 'Object')的问题。该问题的出现原因是由于HttpClient默认将响应的内容反序列化为一个对象,一些方法允许传入泛型类型参数以进行鸭式类型检查,因此就没有了json()方法。

解决方法是通过使用泛型来指定返回结果的类型。在fetch方法中,使用Observable来指定返回的结果类型。同时,在map操作符中,将结果强制转换为Order[]类型,如果res.results为null,则返回一个空数组。

下面是修改后的代码示例:

import { HttpClient, HttpParams } from '/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
export interface Order {
  // Properties
}
export class FooService {
  constructor(private http: HttpClient) {}
  fetch(startIndex: number, limit: number): Observable {
    let params = new HttpParams();
    params = params.set('startIndex', startIndex.toString()).set('limit', limit.toString());
    // base URL should not have ? in it at the end
    return this.http.get(this.baseUrl, {
      params
    })
      .map(res => res['results'] as Order[] || []);
  }
}

通过以上修改,可以解决(Property 'json' does not exist on type 'Object')的问题。同时,可以将返回的Observable转换为Promise,只需调用toPromise()方法。

感谢以上代码的作者提供了解决方案,并提供了一些额外的讨论和建议。以上代码已经通过测试,可以正常使用。

0