angular2 map data as specific object type

前端 未结 4 1985
梦如初夏
梦如初夏 2021-01-04 13:50

I created a very simple app based on the Angular2 tutorial.

To start, I have a very simple \"Book\" model:

 /**
 * book model
 */
export class Book          


        
相关标签:
4条回答
  • 2021-01-04 14:03

    Good practice is to consume data from GET response using

    Observable<Model>
    

    (regarding to Angular documentation https://angular.io/guide/http) And then:

    // imports

    import {HttpClient} from "@angular/common/http";
    

    // in constructor parameter list

    private http: HttpClient
    

    // service method

    getBook(): Observable<Book> {return this.http.get<Book>({url}, {options});}
    
    0 讨论(0)
  • 2021-01-04 14:13

    Yes, casting an object to a type in TypeScript doesn't create an instance of this type. It's just a facility of TypeScript for type checking.

    If you want actually an instance of Book you need to use something like that:

    return this._http.get('getBook/1')
        .map(function(res){
            var data = res.json();
            return new Book(data.id, data.title, data.pages);
        })
    

    To answer your question. In fact if you only have fields into your type (with an interface for example), casting is enough. Moreover if you have methods you want to use later, it's necessary to implicitly create an instance of the Book type (see above) instead of casting. Otherwise you won't be able to use them (they will be undefined on your object)...

    See this question for more details:

    • How do I cast a JSON object to a typescript class
    0 讨论(0)
  • 2021-01-04 14:20

    From https://angular.io/guide/http#requesting-a-typed-response

    To specify the response object type, first define an interface with the required properties. Use an interface rather than a class, because the response is a plain object that cannot be automatically converted to an instance of a class.

    Always receive response using interface because only thing that's happening is mapping fields, and you cannot use class if you have instance function which will throw error when you use that object.

    product.getPrice is not a function
    

    Example

    interface ProductInterface {
      id: number;
      name: string;
      price: number;
    }
    
    class Product implements ProductInterface {
      id: number;
      name: string;
      price: number;
      
      constructor(productData: ProductInterface) {
        this.id = product.id;
        this.name = product.name;
        this.price = product.price;
      }
      
      public getPrice(): string {
        return this.price + " INR";
      }
    }
    
    class ProducService {
      ...
      ...
    
    
      getProduct(): Observable<Product> {
        return this.http.get<Product>('assets/product.json').pipe(map(data => new Product(data))); 
      }
    
      getProductWithoutMappingToClass(): Observable<Product> {
        return this.http.get<Product>('assets/product.json');
      } // Throw runtimerror ctx_r1.product.getPrice is not a function
    }
    
    
    0 讨论(0)
  • 2021-01-04 14:21

    I think you should declare an interface Book instead of class book:

    export interface Book {
        public id;
        public title:string;
        public pages:Array;
    }
    

    In your service:

    //get one record
    return this._http.get('getBook/1')
            .map(function(res){
                return <Book> res.json();
            });
    
    //get multi record
    return this._http.get('getBooks')
            .map(function(res){
                return <Book> res.json();
            });
    
    0 讨论(0)
提交回复
热议问题