JSON map for TS class. If property is obj and not found in JSON, class must have empty obbj

I cannot think of a suitable title for the problem I am facing. Therefore, I will try to explain the problem in as much detail as possible.

I have a specific class: Model.ts

export class Model{
    a:ObjA;
    b:ObjB;
    c:ObjC;
    d:string;
    e:boolean;
    constructor(){
        this.a = new ObjA();
        this.b = new ObjB();
        this.c = new ObjC();    
    }
}

      

Subroutines are saved just for the question ObjA.ts

export class ObjA{
    propA:string;
    propB:ObjD;
    constructor(){
        this.propB = new ObjD();
    }
}

      

ObjB.ts

export class ObjB{
    propA:string;
    propB:number;
}

      

ObjC.ts

export class ObjC{
    propA:string;
    propB:number;
}

      

Now from the service I am getting the following JSON

{a:{propA:"some val"},c:{propB:12},d:"blah"}

      

I wish that I could assign JSON to a class Model

to get this

{a:{propA:"some val",propB:{}},b:{},c:{propB:12},d:"blah"}

      

Using Object.assign(new Model(),json)

gives me

{a:{propA:"some val"},c:{propB:12},d:"blah"}

      

Note the absence here b

. And also a

missingpropB

So my question is, how do I map the json so that if any property that is an object is missing from the json, it will just create an empty object? (I am open to using loadash and such utils)

PS: In this case I am writing an Angular2 application in which properties are entered using a form. If I use the elvis operator in html (obj? .Prop) because obj does not have this property, the value for that property is never set. If I don't use elvis then it gets old undefined

.

Sample form:

...
    <input [(ngModel)]="model.a.propA"/>
    <input [(ngModel)]="model.a.propB"/>
    <input [(ngModel)]="model.b.propA"/>
    <input [(ngModel)]="model.b.propB"/>
    .
    .
    .
...

      

The corresponding * .ts component

class Component implements OnInit{
  ....
  model:Model = new Model();
  ngOnInit(){
    getData().subscribe(res=>Object.assign(model,res));
  }
}

      

+3


source to share


1 answer


You can use Object.assign

in conjunction with the default object you are creating. You will end up merging the properties of both objects, and JSON will override the defaults:

let defaultObj  = { a: "default value a", b: "default value b" };

let json = { a: "json value a" };

let model = Object.assign({}, defaultObj, json);

      

Result:



{a: "json value a", b: "default value b"}

      

However, this is only a shallow copy of the properties from defaultObj

and json

. Since some of your properties are objects, you might want to deeply clone the result Object.assign

so that you don't share the same object between different bindings in your view.

Edit: As mentioned in the comments, libraries like underscore provide features like _.merge

that would be both merge and deep cloning.

+3


source







All Articles