Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular2 map data as specific object type

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 {
    public data;

    /**
     * constructor
     * @param id
     * @param title
     * @param pages
     */
    constructor(
        public id,
        public title:string,
        public pages:Array
    ){
        alert('it works'); // just a check
    }
}

In my service, I get a book like this:

return this._http.get('getBook/1')
        .map(function(res){
            return <Book> res.json();
        })

My expectation was that this would get the resulting JSON data and "map" it to a Book object.

However, it just returns an object with type "Object".

I could create a new Book object myself and pass the parameters in the constructor, like this:

return new Book(res.id, res.title, res.pages);

Is this the best way to do this? Did I miss something?

like image 378
Kris Avatar asked Apr 28 '16 10:04

Kris


2 Answers

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
}

like image 112
Tenzin Chemi Avatar answered Sep 24 '22 14:09

Tenzin Chemi


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();
        });
like image 22
dieuhd Avatar answered Sep 26 '22 14:09

dieuhd