1

I want to convert object literal list from JSON file to particular class object list in javascript, I tried but not able to achieve, can anybody knows how to achieve this in ES5/ES6, since Im trying this in angular 2:

Here is my JSON file:

{"list":[
    {"name":"ABC", "cost":200},
    {"name":"LMN", "cost":100},
    {"name":"POP", "cost":200},
    {"name":"OEE", "cost":560},
    {"name":"WWO", "cost":450},
    {"name":"ERR", "cost":150},
    {"name":"OWE", "cost":250}
]}

Product Class :

export class Product{
static newId:number = 0;

constructor(public name: string = "", public cost: number = 0,public id: number = 0){
    this.id = ++Product.newId;
}};

Here "list" array contains list of object literals of type Object, I just want to convert all of them into the object of type "Porduct"

Here is what im tring to do:

this.appService.getProductList().subscribe(
    data => this.productList = data.list,
    error => console.error("error"),
    () => console.log("GET done.")
  );

Here "appService" is http service, "getProductList()" is service method returns observable, and "this.productList" is an array, I want to fill this array with object of type Product rather simple "Object". Please help me in this.

4 Answers 4

5

Late answer, but wanted to add one aspect:

While in most situations creating a new object with the old object as parameter(s) is definitely the best and safest, it's also possible to modify the prototype of an existing object, to effectively make a simple {"name":"ABC", "cost":200} into a Product.

Example:

class Greeter {
  constructor(public name: string) {
  }

  hello() {
    console.log(`Hello ${this.name}!`);
  }
}

const obj = {name: 'World'}; // Normal object literal which is not a Greeter instance

obj.hello(); // Error
Object.setPrototypeOf(obj, Greeter.prototype); // Now obj is a Greeter instance
obj.hello(); // Prints 'Hello world!'

If using TypeScript, you would also either have to cast obj into a Greeter afterwards or just use the fact that Object.setPrototypeOf returns the given object typed using the given Prototype:

Object.setPrototypeOf(obj, Greeter.prototype); 
const greeter = obj as Greeter;

or, simpler:

const greeter = Object.setPrototypeOf(obj, Greeter.prototype); 

Now obj is a Greeter instance (but still of type{name: string} so you cannot do obj.hello()), but greeter is of type Greeter.

> obj.hello();
error TS2339: Property 'hello' does not exist on type '{ name: string; }'

> greeter.hello();
Hello World!

Obviously, this might be risky and should only be done with care, since you're asserting that an object not created with Greeter's constructor is a compatible object having the same properties etc. So in most cases this should probably be avoided, but it's definitely possible.

Sign up to request clarification or add additional context in comments.

Comments

3

In your getProductList() in the .map call just transform it to a "real" product:

return this.http.get(...)
           .map(res => res.json().map(p => new Product(p.name, p.cost)));

I wouldn't do it in the subscribe because as a consumer of the getProductList() I'd assume to actually already get Products and not just JS objects. The consumer doesn't need to know anything about the implementation detail.

5 Comments

thanks for this answer, I have one doubt, In this example Im useing other angular component in that Im using like this: private model:Product = new Product(); but im not able to get the current product id since its not asyc, what would I do to get the current product id.
I don't really understand that question. What are you trying to achieve?
<input-comp></input-comp> <ul> <li *ngFor = 'let product of productList'> {{product.name}} </li> </ul> Here I'm using input-comp component and in that component Im again creating one variable like: ` private model:Product = new Product();` but if i trace model.id im getting '1', I want the current id which is in this case will be '8'
Well, this component creates its product, before your getProductList() returns, that's why it's getting the id 1.
Its means I need async behavior to achieve this., thanks a lot.
2

I guess this is what you want:

  this.appService.getProductList().subscribe(
    data => this.productList = data.list.map(item => new Product(item.name, item.cost)); 
    error => console.error("error"),
    () => console.log("GET done.")
  );

Comments

0
this.appService.getProductList().subscribe(
    data => this.productList = data.list.map( (listItem) => new Product(listItem),
    error => console.error("error"),
    () => console.log("GET done.")
  );

1 Comment

@Günter Zöchbauer, thanks, I really appreciated your replay

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.