shakilsiraj / json-object-mapper

A TypeScript library to serialize and deserialize object graph from/to JSON in a fast and non-recursive way
MIT License
58 stars 18 forks source link

Only Deserializing 2 Levels Deep #9

Open bassrock opened 7 years ago

bassrock commented 7 years ago

Currently I have object that are nested 3-4 levels deep. However the library is currently only serializing 2 levels deep.

Is there an option somewhere to make the library deserialize deeper?

bassrock commented 7 years ago

I should also note all my objects have custom types. And that it is creating objects 3 levels deep but not creating the objects with my custom types 3 levels deep.

shakilsiraj commented 7 years ago

Hi there,

There is no limit to how deep you can go. Here are some examples you can look at: https://github.com/shakilsiraj/json-object-mapper/blob/master/src/test/DeserializeDataset.spec.ts https://github.com/shakilsiraj/json-object-mapper/blob/master/src/test/DeserializeLargeDataset3.spec.ts

Can you provide a testcase that I can try?

bassrock commented 7 years ago

So its deserializing but its not deserializing to the custom types. And upon further inspection it looks like it is not deserializing any custom nested objects.

My code looks like this:

getProjectList() {
        return this.http.get(this.usersURL + 'projects/' + '1' + '/limit/' + '6')
          .map((response: Response) => {
               const projectUserList: ProjectUser[] = ObjectMapper.deserializeArray(ProjectUser, response.json());
        });
}
export class ProjectUser {

  @JsonProperty({name: 'id'})
  id: string = undefined;

  @JsonProperty({ type: Date, deserializer: DateSerializerDeserializer, serializer: DateSerializerDeserializer, name: 'created_at'})
  createdAt: Date = undefined;

  @JsonProperty({ type: Date, deserializer: DateSerializerDeserializer, serializer: DateSerializerDeserializer, name: 'updated_at'})
  updatedAt: Date = undefined;

  @JsonProperty({type: User, name: 'user'})
  user: User = undefined;

  @JsonProperty({type: Address, name: 'address'})
  address: Address = undefined;
}
export class Address {
  @JsonProperty({name: 'id'})
  id: string = undefined;

  @JsonProperty({ type: Date, deserializer: DateSerializerDeserializer, serializer: DateSerializerDeserializer, name: 'created_at'})
  createdAt: Date = undefined;

  @JsonProperty({ type: Date, deserializer: DateSerializerDeserializer, serializer: DateSerializerDeserializer, name: 'updated_at'})
  updatedAt: Date = undefined;

  @JsonProperty({name: 'street_address_line1'})
  streetAddressLine1: string = undefined;

  @JsonProperty({name: 'street_address_line2'})
  streetAddressLine2: string = undefined;
}

When I breakpoint and look at the ProjectUser object and then at the Address object all the primitive and custom deserializer date values are deserialized properly but not the Address object underneath.

It looks like the deserialize function may not be taking note of the custom type annotation.

bassrock commented 7 years ago

I also tried to pull the library and run the karma tests to make a test case but I couldn't get that running either. Can you provide some documentation on how to run the test cases in the readme?

bassrock commented 7 years ago

@shakilsiraj So stepping through a debugger it seems the reflector library is not returning the type parameter to the deserializer.

bassrock commented 7 years ago

And even more weird. Nested objects of the same type of the parent object seem to work inside.

bassrock commented 7 years ago

Ok definitely something with the Reflect library as I tried this:

const stuff = Reflect.getMetadata("JsonProperty", projectUserList[0], 'createdAt');

That returns: screen shot 2017-06-08 at 4 07 21 pm

While:

const stuff = Reflect.getMetadata("JsonProperty", projectUserList[0], 'user');

Returns: screen shot 2017-06-08 at 4 08 42 pm

So there is something up with the types annotation.

bassrock commented 7 years ago

I think it might be the same as: https://github.com/jf3096/json-typescript-mapper/issues/19

But not sure how to do it with different class files.

bassrock commented 7 years ago

Hmm so changing my imports around change things, but I use the same objects in various places so not sure what to do here.

tomas-ortega commented 7 years ago

Ex. I have 1 nested class, address instance inside person instance: class Address { @JsonProperty({name: "id"}) public _id: number;

public constructor() {
    this._id = undefined;
}

}

class Person { @JsonProperty({name: "id"}) public _id: number;

@JsonProperty({name: "address"})
public _address: Address;

public constructor() {
    this._id = undefined;
    this._address = undefined;
}

}

Serialization Result: { id: 3, address: { id: 32 } } (Working) Deserialization Result: Person { _id: 3, _address: { id: 32 } } (Not Working, _address.id)