3

I have a fairly standard service returning some JSON.

An example return body could be:

[{ a: 1, b: 2 }]

I want to map this to instances of the following Typescript class:

export class MyClass {
  a: number;
  b: number;

  get c() : number {
      return this.a + this.b;
  }
}

I incorrectly assumed HttpClient.get would do exactly this, but while it does map it to compatible objects, they are missing the property.

this.http.get<MyClass[]>('http://www.example.com/endpoint');

Is there a way to get Angular to do this automatically, or do I need to a manual mapping like this:

.map(data => {
    const results : MyClass[];
    for(const d of data) {
        const mc = new MyClass();
        mc.a = d.a;
        mc.b = d.b;
        results.push(mc);
    }
    return results;
});

It works, but it is tedious code to write and can easily create dependencies I do not want in my code.

2 Answers 2

4

1) You can create some parse function like

const mapJsonToObject = Type => obj => Object.assign( new Type(), obj );

And use it like

...
.map( data => mapJsonToObject(MyClass) )
...

2) In other way, you can assign all properties in class constructor

export class MyClass {
  a: number;
  b: number;

  constructor(obj: MyClass) {
    Object.assign( this, obj );
  }

  get c() : number {
      return this.a + this.b;
  }
}

And in map simply create new entity of MyClass

...
.map( data => new MyClass( data as MyClass ) )
...
Sign up to request clarification or add additional context in comments.

1 Comment

@H.B. beat you to it, but that is a much better solution for simple cases, thanks.
1

Angular has no access to the generic type arguments like that. It's just a compiler annotation. In cases of JSON mapping, i tend to write a static parse function in the target class and then just map the plain object over that.

If you do not mangle class names and properties, you can use key iteration to automatically map properties to some degree (only works well for simple types without much additional code).

2 Comments

Ah.. Not the answer I was hoping for, but an answer none the less, thanks :) (I'll accept later when I'm allowed to)
In simple cases like this, Object.assign actually gets you there already: Object.assign(new MyClass(), d).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.