infinum / datx

DatX is an opinionated JS/TS data store. It features support for simple property definition, references to other models and first-class TypeScript support.
https://datx.dev
MIT License
140 stars 7 forks source link

Map option not working properly in combination with parse #1144

Closed stefan-willems-beech closed 1 year ago

stefan-willems-beech commented 1 year ago

Used libraries

core, jsonapi, jsonapi-angular, utils

Library version(s)

"@datx/core": "2.4.6", "@datx/jsonapi": "2.4.6", "@datx/jsonapi-angular": "2.4.7",

Sample API response (if relevant)

{"jsonapi":{"version":"1.0"},"links":{"self":"http:\/\/localhost\/api\/v1\/orders\/1"},"data":{"type":"orders","id":"1","attributes":{"reference":"asdasdasd","status":1,"retrieve_at":"2023-01-20T11:19:52.000000Z","created_at":"2023-01-20T11:19:54.000000Z","updated_at":"2023-01-20T11:19:55.000000Z"},"relationships":{"order-lines":{"links":{"related":"http:\/\/localhost\/api\/v1\/orders\/1\/order-lines","self":"http:\/\/localhost\/api\/v1\/orders\/1\/relationships\/order-lines"},"data":[{"type":"order-lines","id":"1"},{"type":"order-lines","id":"2"},{"type":"order-lines","id":"3"}]}},"links":{"self":"http:\/\/localhost\/api\/v1\/orders\/1"}},"included":[{"type":"order-lines","id":"1","attributes":{"amount":3,"bigbag_type":1,"has_pallet":1,"created_at":"2023-01-20T12:50:26.000000Z"},"relationships":{"product":{"links":{"related":"http:\/\/localhost\/api\/v1\/order-lines\/1\/product","self":"http:\/\/localhost\/api\/v1\/order-lines\/1\/relationships\/product"},"data":{"type":"products","id":"1"}}},"links":{"self":"http:\/\/localhost\/api\/v1\/order-lines\/1"}},{"type":"products","id":"1","attributes":{"reference":"101005","description":"Aquado General 0\/8 mm","createdAt":"2023-01-20T11:49:58.000000Z","updatedAt":"2023-01-20T11:49:58.000000Z"},"links":{"self":"http:\/\/localhost\/api\/v1\/products\/1"}},{"type":"order-lines","id":"2","attributes":{"amount":4,"bigbag_type":2,"has_pallet":0,"created_at":"2023-01-20T12:50:26.000000Z"},"relationships":{"product":{"links":{"related":"http:\/\/localhost\/api\/v1\/order-lines\/2\/product","self":"http:\/\/localhost\/api\/v1\/order-lines\/2\/relationships\/product"},"data":{"type":"products","id":"14"}}},"links":{"self":"http:\/\/localhost\/api\/v1\/order-lines\/2"}},{"type":"products","id":"14","attributes":{"reference":"100590","description":"Basaltsplit 0\/2 mm","createdAt":"2023-01-20T11:49:58.000000Z","updatedAt":"2023-01-20T11:49:58.000000Z"},"links":{"self":"http:\/\/localhost\/api\/v1\/products\/14"}},{"type":"order-lines","id":"3","attributes":{"amount":2,"bigbag_type":2,"has_pallet":0,"created_at":"2023-01-20T12:50:26.000000Z"},"relationships":{"product":{"links":{"related":"http:\/\/localhost\/api\/v1\/order-lines\/3\/product","self":"http:\/\/localhost\/api\/v1\/order-lines\/3\/relationships\/product"},"data":{"type":"products","id":"3"}}},"links":{"self":"http:\/\/localhost\/api\/v1\/order-lines\/3"}},{"type":"products","id":"3","attributes":{"reference":"100975","description":"Aquado Natural 0\/8 mm","createdAt":"2023-01-20T11:49:58.000000Z","updatedAt":"2023-01-20T11:49:58.000000Z"},"links":{"self":"http:\/\/localhost\/api\/v1\/products\/3"}}]}

Environments with the issue

Chrome 109.0.5414.74, Ubuntu 22.04.1 LTS

Environments without the issue

No response

Current behavior

Current Object inside Angular.

{
    "created_at": "2023-01-20T11:19:54.000000Z",
    "createdAt": null,
    "reference": "asdasdasd",
    "retrieve_at": "2023-01-20T11:19:52.000000Z",
    "retrieveAt": null,
    "status": 1,
    "orderLines": [
        {
            "id": "1",
            "type": "order-lines"
        },
        {
            "id": "2",
            "type": "order-lines"
        },
        {
            "id": "3",
            "type": "order-lines"
        }
    ],
    "updated_at": "2023-01-20T11:19:55.000000Z",
    "order-lines": [
        {
            "id": "1",
            "type": "order-lines"
        },
        {
            "id": "2",
            "type": "order-lines"
        },
        {
            "id": "3",
            "type": "order-lines"
        }
    ]
}

Current Order model:

export class Order extends BaseModel {
    static type = 'orders';

    @Attribute() public amount: number;

    @Attribute({
        map: 'created_at',
        parse: (value: string) => moment(value),
        serialize: (value: moment.Moment) => value?.toISOString()
    }) public createdAt?: moment.Moment = null;

    @Attribute() public reference: string;

    @Attribute({
        map: 'retrieve_at',
        parse: (value: string) => moment(value),
        serialize: (value: moment.Moment) => value?.toISOString()
    }) public retrieveAt?: moment.Moment = null;

    @Attribute() public status: OrderStatus;

    @Attribute({toOneOrMany: OrderLine, map: 'order-lines'}) public orderLines: OrderLine[];
}

I am currently getting duplicate attributes inside my model (which is not the biggest problem, but not needed), where as the fields created_at and retrieve_at are fully ignoring the parse method given to them.

Expected behavior

{
    "created_at": Moment (Moment date object),
    "reference": "asdasdasd",
    "retrieve_at": Moment (Moment date object),
    "status": 1,
    "order-lines": [
        {
            "id": "1",
            "type": "order-lines"
        },
        {
            "id": "2",
            "type": "order-lines"
        },
        {
            "id": "3",
            "type": "order-lines"
        }
    ]
}

Reproduction steps

No response

stefan-willems-beech commented 1 year ago

Also not working under the following versions: "@datx/core": "^2.4.11", "@datx/jsonapi": "^2.4.11", "@datx/jsonapi-angular": "^2.4.11", "@datx/utils": "^2.4.8",

stefan-willems-beech commented 1 year ago

Fixed this issue.

Changed:

@Attribute({
        map: 'created_at',
        parse: (value: string) => moment(value),
        serialize: (value: moment.Moment) => value?.toISOString()
    }) public createdAt?: moment.Moment = null;

To:

@Attribute({
        map: 'created_at',
        parse: (value: string) => value ? moment(value) : null,
        serialize: (value: moment.Moment) => value?.toISOString()
    }) public createdAt?: moment.Moment;