“Type 'Object' is not assignable to type” with new HttpClient / HttpGetModule

后端 未结 2 775
我寻月下人不归
我寻月下人不归 2020-12-03 10:52

Following Google\'s official Angular 4.3.2 doc here, I was able to do a simple get request from a local json file. I wanted to practice hitting a real endpoint

相关标签:
2条回答
  • 2020-12-03 11:39

    I'm on the Angular doc team and one open todo item is to change these docs to show the "best practice" way to access Http ... which is through a service.

    Here is an example:

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpErrorResponse } from '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/observable/throw';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/operator/do';
    import 'rxjs/add/operator/map';
    
    import { IProduct } from './product';
    
    @Injectable()
    export class ProductService {
        private _productUrl = './api/products/products.json';
    
        constructor(private _http: HttpClient) { }
    
        getProducts(): Observable<IProduct[]> {
            return this._http.get<IProduct[]>(this._productUrl)
                .do(data => console.log('All: ' + JSON.stringify(data)))
                .catch(this.handleError);
        }
    
        private handleError(err: HttpErrorResponse) {
            // in a real world app, we may send the server to some remote logging infrastructure
            // instead of just logging it to the console
            let errorMessage = '';
            if (err.error instanceof Error) {
                // A client-side or network error occurred. Handle it accordingly.
                errorMessage = `An error occurred: ${err.error.message}`;
            } else {
                // The backend returned an unsuccessful response code.
                // The response body may contain clues as to what went wrong,
                errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
            }
            console.error(errorMessage);
            return Observable.throw(errorMessage);
        }
    }
    

    The component would then look like this:

    ngOnInit(): void {
        this._productService.getProducts()
                .subscribe(products => this.products = products,
                           error => this.errorMessage = <any>error);
    }
    
    0 讨论(0)
  • 2020-12-03 11:43

    You actually have a few options here, but use generics to cast it to the type you're expecting.

       // Notice the Generic of IUsers[] casting the Type for resulting "data"
       this.http.get<IUsers[]>(this.productUrl).subscribe(data => ...
    
       // or in the subscribe
       .subscribe((data: IUsers[]) => ...
    

    Also I'd recommend using async pipes in your template that auto subscribe / unsubscribe, especially if you don't need any fancy logic, and you're just mapping the value.

    users: Observable<IUsers[]>; // different type now
    
    this.users = this.http.get<IUsers[]>(this.productUrl);
    
    // template:
    *ngFor="let user of users | async"
    
    0 讨论(0)
提交回复
热议问题