Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@Json support formatting deep JSON object #128

Open
etsuo opened this issue Jan 31, 2018 · 0 comments
Open

@Json support formatting deep JSON object #128

etsuo opened this issue Jan 31, 2018 · 0 comments

Comments

@etsuo
Copy link
Member

etsuo commented Jan 31, 2018

#124 #96 were implemented on 0.9.0, but fail to take into account some scenarios.
#126 takes care of this at a Model level. This ticket address the more specific property level handling.

The Problem

There are times when incoming JSON from a service may not be in the the shape we want. By shape, I mean that it's not simply field name transformation that we want to accomplish, it's also morphing the shape of the incoming JSON such that it results in a Model that has a different shape.

Incoming JSON:

const data = {
    "first_name": "john",
    "source": {
        "address_1": "123 main st",
        "address_2": "suite 100
    }
}

Desired result from SomeModel.fromJson(data, 'source1'):

{
  firstName: 'john',
  address: '123 main st suite 100"
}

It may also be the case that the incoming JSON comes in multiple shapes depending on the source, but the resulting Model is common to those various sources. For example the following might also be incoming JSON from a different source that would result in SomeModel above.

const data = {
    "firstName": "john",
    "address": "123 main st suite 100"
}

And it should be the case that you can marshall a Model back to its original shape (someModel.toJson('source1')):

{
    "first_name": "john",
    "source": {
        "address_1": "123 main st",
        "address_2": "suite 100
    }
}

or with someModel.toJson():

const data = {
    "firstName": "john",
    "address": "123 main st suite 100"
}

Proposed API:

@Model()
class SomeModel {
  @Json()
  @Json('first_name', 'source1')
  firstName: string;

  @Json()
  @Json({
    field: 'source',
    formatFromJson: this.buildModelAddress,
    formatToJson: this.buildJsonAddress,
  }, 'source1')
  address: string;

  private buildModelAddress(val, key) {
    return `${val.address_1} ${val.address_2}`;
  }

  private buildJsonAddress(val, key, obj) {
    const parts = val.split(' ');
    obj.source = obj.source || {};
    obj.source.address_1 = parts[0];
    obj.source.address_2 = parts.length > 1 ? parts[0] : undefined;
    return val;
  }
}

For formatFromJson, val will be the child object source (which fromJson will not recurse into).

For formatToJson, val will be the address string of the model, and a new parameter, obj will be passed in, which is the root of the object being built.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant