user9397302
user9397302

Reputation:

Angular6 upgrade issue: Property 'data' does not exist on type 'Object'

I am upgrading my angular app from v5 to 7.

I have done all of the migration steps mentioned in Angular update guide. But I am facing an issue with my existing code.

myservice.service.ts

import {Injectable, Inject} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Response, Headers, RequestOptions} from "@angular/http";

@Injectable()
export class MyApiService{
    constructor(private http: HttpClient, @Inject(MY_HOST) private host: string) 
    {
        this.host = this.host + "/api/common";
    }
    getNotification (appName) {
        return this.http.get(this.host + "/notifications")
    }   
}

my-component.component.ts

import {combineLatest as observableCombineLatest, Subject, Observable, Subscription} from 'rxjs';
import {MyApiService} from "../../shared/services/myservice.service";

@Component({..// template and style url...});

export class NotificationComponent implements OnInit{
    constructor(private myApiService: MyApiService)

 getNotification(): void {
     this.myApiService.getNotification('myApp').subscribe(response => {
        console.log(response.data); **// ERROR: It throws error here. Property** 'data' does not exist on type 'Object'.
    }, (error: void) => {
      console.log(error)
   })
 }

}

Upvotes: 5

Views: 7584

Answers (2)

Chrillewoodz
Chrillewoodz

Reputation: 28338

You must use any or a custom response type since data doesn't exist on type {}:

.subscribe((response: any) => ...)

A custom response interface is the best solution:

export interface CustomResponse {
  data: any;
}

.subscribe((response: CustomResponse) => ...)

Note that you can also use the type like this:

this.httpClient.get<CustomResponse>(...)
  .subscribe((response) => ...) // response is now CustomResponse

Upvotes: 17

Juan M. Medina
Juan M. Medina

Reputation: 638

See this example from the angular documentation for HTTPClient:

Service code:

getConfigResponse(): Observable<HttpResponse<Config>> {
  return this.http.get<Config>(
    this.configUrl, { observe: 'response' });
}

Consumer Code:

showConfigResponse() {
  this.configService.getConfigResponse()
    // resp is of type `HttpResponse<Config>`
    .subscribe(resp => {
      // display its headers
      const keys = resp.headers.keys();
      this.headers = keys.map(key =>
        `${key}: ${resp.headers.get(key)}`);

      // access the body directly, which is typed as `Config`.
      this.config = { ... resp.body };
    });
}

By declaring the return type explicitly on the service they can avoid having to declare it on the subscription inner logic because the code is strongly typed.

Upvotes: 0

Related Questions