GillianPerard / typescript-json-serializer

A typescript library to deserialize json into typescript classes and serialize classes into json.
MIT License
210 stars 29 forks source link

Cannot read property 'name' of undefined #132

Closed LucasDshg closed 3 years ago

LucasDshg commented 3 years ago

Hey dude! I'm using your nice lib. but today i got a error where just ocurred when i run ng buil -- prod

So this bug is: if in this class of object not have some name of JsonProperty that has in the response i got this error. Screenshot 2021-04-15 174013

this is my class object

@Serializable()
export class Vehicle {

  constructor(init?: Partial<Vehicle>) {
    Object.assign(this, init);
  }

  @JsonProperty('CLV_CD_CLIENTE_VEICULO')
  idClientVehicle?: number = 0;

  @JsonProperty('CLV_DS_VEICULO')
  name?: string = undefined;

  @JsonProperty('CLV_DS_PLACA')
  board?: string = undefined;

  @JsonProperty('CLV_DS_CARTAO')
  card?: string = undefined;

  @JsonProperty('CLV_VL_LIMITE_REAIS')
  limitReais?: number = undefined;

  @JsonProperty('CLV_VL_LIMITE_LITROS')
  limitLiter?: number = undefined;

  @JsonProperty('CLV_FL_ATIVO')
  state?: boolean | STATUS = STATUS.ACTIVE;

  @JsonProperty('CLV_VL_LIMITE_DISPONIVEL_REAIS')
  limitReaisAvailable?: number = undefined;

  @JsonProperty('CLV_VL_LIMITE_DISPONIVEL_LITROS')
  limitLiterAvailable?: number = undefined;

  @JsonProperty('CCC_DS_DESCRICAO')
  description?: string = undefined;

  @JsonProperty({ name: 'CLV_DT_VALIDADE_TACOGRAFO', beforeDeserialize: stringToDate, beforeSerialize: dateToString })
  dateTacografo?: Date = undefined;

}

export function deserializeVehicle(value) {
  return deserializer({ OBJ: value }, VehicleArray).array;
}
@Serializable()
class VehicleArray {
  @JsonProperty({ name: 'OBJ', type: Vehicle })
  array: Vehicle[];
}

This is the response

[
    {
        "CLV_CD_CLIENTE_VEICULO": 316005,
        "CLV_DS_VEICULO": "ASDASDASD",
        "CLV_DS_PLACA": "ASD-3434",
        "CLV_VL_LIMITE_REAIS": 0,
        "CLV_VL_LIMITE_DISPONIVEL_REAIS": 0,
        "CLV_VL_LIMITE_LITROS": 0,
        "CLV_VL_LIMITE_DISPONIVEL_LITROS": 0,
        "CLV_DS_CARTAO": null,
        "CLV_FL_ATIVO": "S",
        "CCC_CD_CLIENTE_CENTRO_CUSTO": 372,
        "CCC_DS_DESCRICAO": "ADMINISTRAÇÃO",
        "CLV_FL_LIMITE_REAIS": "S",
        "CLV_FL_LIMITE_LITROS": "N",
        "CLV_DT_VALIDADE_TACOGRAFO": "26/03/2021"
    },
    {
        "CLV_CD_CLIENTE_VEICULO": 258022,
        "CLV_DS_VEICULO": "CARRO",
        "CLV_DS_PLACA": "KKK-7777",
        "CLV_VL_LIMITE_REAIS": 333.2,
        "CLV_VL_LIMITE_DISPONIVEL_REAIS": 333.2,
        "CLV_VL_LIMITE_LITROS": 333.33,
        "CLV_VL_LIMITE_DISPONIVEL_LITROS": 333.33,
        "CLV_DS_CARTAO": "S",
        "CLV_FL_ATIVO": "S",
        "CCC_CD_CLIENTE_CENTRO_CUSTO": 372,
        "CCC_DS_DESCRICAO": "ADMINISTRAÇÃO",
        "CLV_FL_LIMITE_REAIS": "S",
        "CLV_FL_LIMITE_LITROS": "S",
        "CLV_DT_VALIDADE_TACOGRAFO": "31/03/2021"
    },
    {
        "CLV_CD_CLIENTE_VEICULO": 371333,
        "CLV_DS_VEICULO": "DADASDSA",
        "CLV_DS_PLACA": "ASDASDA",
        "CLV_VL_LIMITE_REAIS": 0,
        "CLV_VL_LIMITE_DISPONIVEL_REAIS": 0,
        "CLV_VL_LIMITE_LITROS": 0,
        "CLV_VL_LIMITE_DISPONIVEL_LITROS": 0,
        "CLV_DS_CARTAO": null,
        "CLV_FL_ATIVO": "S",
        "CCC_CD_CLIENTE_CENTRO_CUSTO": null,
        "CCC_DS_DESCRICAO": null,
        "CLV_FL_LIMITE_REAIS": "S",
        "CLV_FL_LIMITE_LITROS": "S",
        "CLV_DT_VALIDADE_TACOGRAFO": null
    }
]

So i don't have in my class this names: CLV_FL_LIMITE_REAIS CLV_FL_LIMITE_LITROS CCC_CD_CLIENTE_CENTRO_CUSTO

Are there some thing to resolve this in your lib?

GillianPerard commented 3 years ago

Hi dude, thank you for using my lib!

Let me check what happens.

GillianPerard commented 3 years ago

Could you send me the object you tried to deserialize please?

LucasDshg commented 3 years ago

I've sended in the first post. It's a json array

GillianPerard commented 3 years ago

You told that is the response, I thought it was the result after deserialize when there is no error.

Sorry so 🥴

GillianPerard commented 3 years ago

I tried your code and I can't reproduce the error...

Could you tell me which version of Angular are you using?

A thing that could be great is to provide me a complet example with https://stackblitz.com/.

LucasDshg commented 3 years ago

So i think that u can't reproduce in stackblitz because the just ocuured if i run ng build --prod maybe some problem when the code convert to javascript.

this is my package.json

  "dependencies": {
    "@angular/animations": "~11.2.1",
    "@angular/cdk": "^11.2.1",
    "@angular/common": "~11.2.1",
    "@angular/compiler": "~11.2.1",
    "@angular/core": "~11.2.1",
    "@angular/fire": "^6.1.4",
    "@angular/forms": "~11.2.1",
    "@angular/material": "^11.2.1",
    "@angular/material-moment-adapter": "^11.2.1",
    "@angular/platform-browser": "~11.2.1",
    "@angular/platform-browser-dynamic": "~11.2.1",
    "@angular/router": "~11.2.1",
    "@angular/service-worker": "~11.2.1",
    "@fingerprintjs/fingerprintjs": "^3.0.6",
    "bootstrap": "^5.0.0-beta2",
    "crypto-js": "^4.0.0",
    "custom-lib-angular": "^1.0.8",
    "firebase": "^8.2.6",
    "moment": "^2.29.1",
    "ngx-image-cropper": "^3.3.3",
    "ngx-mask": "^11.1.4",
    "ngx-mat-select-search": "^3.2.0",
    "ngx-webstorage-service": "^4.1.0",
    "remixicon": "^2.5.0",
    "rxjs": "^6.6.3",
    "subsink": "^1.0.2",
    "sweetalert2": "^10.12.5",
    "tslib": "^2.0.0",
    "typescript-json-serializer": "^3.2.2",
    "zone.js": "~0.10.2"
  },
GillianPerard commented 3 years ago

I'll try with your version of Angular.

GillianPerard commented 3 years ago

It works with 11.2...

It brokes during ng build --prod or when you try to start your website?

Did you set the emitDecoratorMetadata to true inside the tsconfig.json?

LucasDshg commented 3 years ago

the app builded but when i do the request to recive a response it's broken.

Yes i set

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ],
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}
GillianPerard commented 3 years ago

What are you using to launch the application after the build?

LucasDshg commented 3 years ago

Angular cli to build. after u can run using http-server or run im a real server. both case it`s broken

cd dist/appname

http-server -c-1

LucasDshg commented 3 years ago

u need to install https://www.npmjs.com/package/http-server

GillianPerard commented 3 years ago
Capture d’écran 2021-04-20 à 14 26 20

I have no problems...

LucasDshg commented 3 years ago

ur object class has all params of arary?

GillianPerard commented 3 years ago

I used the one you provided

LucasDshg commented 3 years ago

humm... So we should close this issue and later i will try to get more details about the error and send u

GillianPerard commented 3 years ago

Ok ok, sorry :/

exaucae commented 3 years ago

Bump!

I've got the exact same error : err

fun fact: code works when I comment @JsonProperty in all class attributes. versions:

usage


const returnMarqueData = (res: { data: any; }) => (
    res.data).map( (marque: any)  => deserialize<Marque>(marque, Marque)
);
const returnTypeData = (res: { data: any; }) => (
    res.data).map( (type: any)  => deserialize<Type>(type, Type)
);

json payload for type and then marque

[
  {
    "data" : {
            "id": 1,
            "name": "foo"
            }
    },
  {
    "data" : 
           {

              "id": 2,
              "name": "bar"
            }
    }
]
[
  {
    "data" : {
            "id": 1,
            "name": "john"
            }
    },
  {
    "data" : 
           {

              "id": 2,
              "name": "doer"
            }
    }
]

classes

import { JsonProperty, Serializable } from 'typescript-json-serializer';

@Serializable()
export class Marque{
    @JsonProperty({ name: 'id' })
    private _id: number;
    @JsonProperty({ name: 'name' })
    private _name: string;

    constructor(id: number, name: string) {
        this._id = id;
        this._name = name;
    }
    public get id(): number {
        return this._id;
    }
    public set id(value: number) {
        this._id = value;
    }
    public get name(): string {
        return this._name;
    }
    public set name(value: string) {
        this._name = value;
    }
}
import { JsonProperty, Serializable } from 'typescript-json-serializer';

@Serializable()
export class Type{
    @JsonProperty({ name: 'id' })
    private _id: number;
    @JsonProperty({ name: 'name' })
    private _name: string;

    constructor(id: number, name: string) {
        this._id = id;
        this._name = name;
    }
    public get id(): number {
        return this._id;
    }
    public set id(value: number) {
        this._id = value;
    }
    public get name(): string {
        return this._name;
    }
    public set name(value: string) {
        this._name = value;
    }
}

tsconfig.json


{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "types": [
    "node",
    "jest",
    "@testing-library/jest-dom"
  ],
  "include": [
    "src"
  ]
}

.babelrc


{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
  ],
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      { "legacy": true }
    ],
    [
      "@babel/plugin-proposal-class-properties",
      { "loose": true }
    ],
    ["@babel/plugin-proposal-private-methods", { "loose": true }],
]
}
GillianPerard commented 3 years ago

Hi, could you try to update typescript-json-serializer to the last version 3.3.0 please?

exaucae commented 3 years ago

My bad, @GillianPerard . Found solution in this previous issue. It was related to cra not supportting reflect-metadata. I configured customize-cra as pointed in the above link.

Maybe, you can add it as a default config in your lib?

GillianPerard commented 3 years ago

My lib is not created specifically for React so I will not add this config directly but I can create a section in the ReadMe to explain how to fix the issue.

Could you provide here the code you added to make it work please 😊.

exaucae commented 3 years ago

That's fair enough. Let me do that ASAP.

pavel-vorobyev commented 3 years ago

Solved it by adding "emitDecoratorMetadata": true to the tsconfig.json file.