Coder Social home page Coder Social logo

shakilsiraj / json-object-mapper Goto Github PK

View Code? Open in Web Editor NEW
58.0 58.0 18.0 2.72 MB

A TypeScript library to serialize and deserialize object graph from/to JSON in a fast and non-recursive way

License: MIT License

TypeScript 99.91% JavaScript 0.09%

json-object-mapper's People

Contributors

artonio avatar dependabot[bot] avatar devpreview avatar dgio-git avatar ironchimp avatar rtrompier avatar shakilsiraj avatar vapkse avatar xavierd1986 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

json-object-mapper's Issues

Readme should be updated with working example

Example from Readme doesn't work properly with TypeScript.

It should be updated or have info about that all classess used by object mapper must be created with constructor or marked all fields as undefined

Custom Serializer / Deserialiser caching does not work with Generic Classes / minimised bundles

Hi,

firstly, thanks for the library - it fits my needs perfectly, however I have encountered a couple of blockers related to the caching of custom de/serializer objects.

From my debugging, it seems that the caching logic uses a function over the string representation of the instantiation method of de/serializer. Under the following circumstances, this results in the incorrect de/serializer being used:

1. Generic classes as custom de/serializers

As I use a lot of ES6 Maps / Sets in my project, I wrote a generic marshalling class to deal with the de/serialisation of the collection. However, the identifier used for the entry into the cache map does not include the generic type specifier.

Example:
Given the following generic Set deserializer definition:

export class SetMarshaller<EntryType> implements Deserializer, Serializer {
  type: {new (): EntryType};

  public constructor(type: {new (): EntryType}) {
    this.type = type;
  }

  public deserialize(values: string[]): Set<EntryType> {
    const setToReturn: Set<EntryType> = new Set();
    if (values) {
      values.forEach(entry => {
        setToReturn.add(ObjectMapper.deserialize(this.type, entry));
      });
    }
    return setToReturn;
  }

  public serialize(value: Set<EntryType>): string {
    const results = [];
    value.forEach(entry => {
      let obj: any = entry;
      if (isObject(entry)) {
        obj = ObjectMapper.serialize(entry).toString();
      }
      results.push(JSON.parse(obj));
    });
    return JSON.stringify(results);
  }

}

Both of the following instantiations will result in the same identifier being used in the cache map:

SetMarshaller<MyCusomObject1>;  // identifier: 'SetMarshaller'
SetMarshaller<YetAnotherCustomObject>; // identifier: 'SetMarshaller'

This will result in every set marshaller using the instanced used for the first encountered SetMashaller during execution of the app.

2. Production builds under Angular CLI

The identity mechanism shows interesting behaviour when running a production build generated by angular-cli.

Specifically, the minification and uglification mechanism replaces the named constructors with generated functions, which obscures the actual name of the construction function, resulting in more frequent clashes in the caching mechanism.

Request

Is it possible to implement some way to allow my de/serializer implementations to specify their own identify function?

Thanks,
Paul Wallace

Problem to serialize a object with null values. [v1.5.0]

When I will serialize an object that may contain nulls the serialization fails.
With version 1.4.0 everything works perfectly.
With version 1.5.0 I get the error that I show below.

example:

In Model:

...
  @JsonProperty({name: 'resubmissionAfterDaysSelected'})
  private _resubmissionAfterDaysSelected: number | null;

  @JsonProperty({name: 'resubmissionAfterMessagesSelected'})
  private _resubmissionAfterMessagesSelected: number | null;
...

Object values:

{
  "_eventId": 2416,
  "_version": 2,
  "_eventStatusSelected": "Open",
  "_userCommentCurrent": "",
  "_falsePositiveSelected": false,
  "_caseNoCurrent": "",
  "_resubmissionAfterDaysSelected": null,
  "_resubmissionAfterMessagesSelected": null
}

Execute:

ObjectMapper.serialize(object)

Error:

TypeError: can't convert null to object
Traza de la pila:
SerializeObjectType@http://localhost:4200/vendor.bundle.js:23906:22

thanks.

Deserialize quoted floats

There seems to be a problem with deserializing floats:

class Test {
    @JsonProperty({ name: 'test_test' }) test: number = 0.00;
}
const data = { test_test: '1.234' };
const testData: Test = ObjectMapper.deserialize(Test, data);
console.log(testData);

Outputs:

Test { test: "1.234" }

deserializeArray returns undefined when called on an empty array

Hi, is this intended behavior?

  class Example {
      hello = null;
      world = null;
    }
    const helloJson = []
    const result = ObjectMapper.deserializeArray(Order, helloJson);

    // expected []
    // was undefined
    console.log(result);

If not, it should be fixed. If so, it should be documented, as it seems like it could cause confusion.

Serialize/deserialize array of enum

Hi.

I have the following use case:

export class LoggedUserModel {

  @JsonProperty({name: 'permissions', type: PermissionEnum
                ,deserializer: PermissionEnumDeserializer})
  public permissions: PermissionEnum[];
}

The enum definition:

export enum PermissionEnum {
  PERMISSION_EXAMPLE_1,
  PERMISSION_EXAMPLE_2,
  PERMISSION_EXAMPLE_3
}

@CacheKey('PermissionEnumDeserializer')
export class PermissionEnumDeserializer implements Deserializer {

  deserialize = (value: string): PermissionEnum => return PermissionEnum[value] as PermissionEnum;
}

And the example of the Json:

{"permissions":["PERMISSION_EXAMPLE_1","PERMISSION_EXAMPLE_2"]}

The problem in this case is that deserialize method always receives whole values of the json, that is, deserialize is invoked twice with whole array values every time.

Serialize / deserialize array didn't keep order

Hi !

If you deserialize a JSON inside an object, and then serialize it, array order are not keeped.

For example

{
    "test": [1,2,3,4,5]
}

can become

{
    "test": [2,1,5,4,3]
}

I think the problem comes from uniqueId() inside SerializeArrayType method.
Could you check it ?

Thanks

Serialize & Deserialize when the class attribute is null

When you have a class with a null vale in some attribute, custom property name in serialization and deserialization processs not work, and json property name is ignored.

Examples are in TypeScript Syntax

Ex. User Domain Class
export class User {

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

@JsonProperty({name: "name"})
public _name: string;

@JsonIgnore()
public _password: string;

public constructor() {
    this._id = null;
    this._name = "Test User Name";
    this._password = "gsa@aglaX!";
}

}

Ex. Serialization
let userInstance: User;
userInstance = ObjectMapper.serialize(singleTestDTO);

User instance: {"_id": null, "name": "Test User Name"}

If don't explicitly initialize _id to null, works, or if initialize to undefined, but no with null value...

It would be wonderful it worked with null values

Congratulations on working with module! ๐Ÿ‘

Repeating deserialisation twice per object

Hi Team,

Please look at the below code segment from index.ts file. It's doing deserialisation twice per object because we are assigning the first element for deserialisation first and then the popped element again.

`const runDeserialization = (conversionFunctionStructures: ConversionFunctionStructure[]): void => {

    const converstionFunctionsArray: Array<ConversionFunctionStructure> = [];
    conversionFunctionStructures.forEach((struct: ConversionFunctionStructure) => {
        converstionFunctionsArray.push(struct);
    });

    **let conversionFunctionStructure: ConversionFunctionStructure = converstionFunctionsArray[0];** //This line needs to be replaced with **let conversionFunctionStructure: ConversionFunctionStructure = (converstionFunctionsArray.length > 0)? converstionFunctionsArray.pop() : undefined;**

    // tslint:disable-next-line:triple-equals
    while (conversionFunctionStructure != undefined) {
        const stackEntries: Array<ConversionFunctionStructure> = conversionFunctions[conversionFunctionStructure.functionName](
            conversionFunctionStructure.instance, conversionFunctionStructure.instanceKey,
            conversionFunctionStructure.type, conversionFunctionStructure.json,
            conversionFunctionStructure.jsonKey);
        stackEntries.forEach((structure: ConversionFunctionStructure) => {
            converstionFunctionsArray.push(structure);
        });
        conversionFunctionStructure = converstionFunctionsArray.pop();
    }
};`

CSP error when used in WebExtension

Hello,

I'm currently writing an extension for Chrome and Firefox and I use json-object-mapper. My issue is that there is a bit of code that violates CSP (Content Security Policy).

Here is the error I get :
Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".

The code that causes this error is const functionImpl = new Function(`return '${key}';`); from src/main/DecoratorMetadata.ts:55.

I tried adding 'unsafe-eval' in the CSP as suggested by the error message, unfortunately, this CSP directive is forbidden in Firefox addons, and my extension got refused...

Is there any way you could fix json-object-mapper so that it doesn't trigger any CSP error please ?

Thanks in advance !

SyntaxError: Unexpected token export

My setup is: Typescript with node on Serverless (AWS lambda). Whenever I call one of the lambda functions, I get the following:

Serverless: Error while loading lambdaFunc
[ '...\\node_modules\\json-object-mapper\\dist\\ObjectMapper.es2015.js:637',
  'export { ObjectMapper, JsonProperty, JsonConverstionError, AccessType, CacheKey, JsonIgnore, DateSerializer };',
'SyntaxError: Unexpected token export',

The lambdaFunc file has the following:

import { ClassName1 } from "foo1";
import { ClassName2 } from "foo2";
import { ClassName3 } from "foo3";

and all those classes have:
import { JsonProperty } from "json-object-mapper";

this works fine. And then as soon as I add this to the lambdaFunc:
import { AnotherClass } from "foo4";
which has:
import { ObjectMapper } from "json-object-mapper";

I get the error above.

SyntaxError: Unexpected token export

I'm pretty new to NodeJS and JS/TS development in general, and I'm lately facing this problem: when I try to compile and execute a little software of mine, the compilation terminates without any error whatsoever, while the execution throws the following error:

node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:637
export { ObjectMapper, JsonProperty, JsonConverstionError, AccessType, CacheKey, JsonIgnore, DateSerializer };
^^^^^^

SyntaxError: Unexpected token export
    at createScript (vm.js:56:10)
    at Object.runInThisContext (vm.js:97:10)
    at Module._compile (module.js:542:28)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> 

My tsconfig.json is this one:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "outDir": "build",
        "sourceMap": true
    },
    "exclude": [
        "node_modules"
    ],
    "include": [
        "src/**/*.ts"
    ]
}

Is something wroong with the package or am I missing something obvious?

Show warning if @CacheKey is not present for custom serializer/deserializer

Hello!

I ran into a problem today, when my production build was throwing misterious errors like t.map is not a function. Spent some hours to localize an issue, then figured out that the reason was deserializers caching strategy, which doesn't work after minification. I've done some research and have read #2. @CacheKey was the solution. I consider it strange, that the problem isn't mentioned in the documentation.

Thus, I wanted to suggest an improvement. The library could warn about missing @CacheKey decorator, so developer would not occasionally shoot himself in the foot on production.

Angular 6

Does this framework still work for Angular 6?

deserializeArray issue

Hello !

I have a problem when I want to deserialize an array. Here is my code:
@JsonProperty({name: 'myArray', required: false, type: Array<models.myVar>()}) public myArray: Array<models.myVar> = undefined;

This thrown an error like this when I use the ObjectMapper.deserialize method:

TypeError: metadata.type is not a constructor
at http://localhost:9876/_karma_webpack_/webpack:/D:/projets/.../node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:303:1
at Array.forEach ()
at Object.DeserializeComplexType D:/projets/.../node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:265:1)
at runDeserialization D:/projets/.../node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:612:1)
at Object.webpackJsonp.../../../../json-object-mapper/dist/ObjectMapper.es2015.js.ObjectMapper.deserialize

I've first modify my code like this:
@JsonProperty({name: 'myArray', required: false, type: Array<models.myVar>()}) public myArray: models.myVar[] = undefined;

But I've this other error:

TypeError: type is not a constructor
at Object.DeserializeArrayType D:/projets/.../node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:222:1)
at http://localhost:9876/_karma_webpack_/webpack:/D:/projets/.../node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:316:1
at Array.forEach ()
at Object.DeserializeComplexType D:/projets/.../node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:265:1)
at runDeserialization D:/projets/.../node_modules/json-object-mapper/dist/ObjectMapper.es2015.js:612:1)
at Object.webpackJsonp.../../../../json-object-mapper/dist/ObjectMapper.es2015.js.ObjectMapper.deserialize

I then modified the DeserializeArrayType method like this:
var typeInstance = new type(); to var typeInstance = type;

And it works now...

Can you tell me if there is a mistake in my or your code ? :)

Thanks a lot !

Marc

Error: Cannot find module 'reflect-metadata'

I am getting the following error:
Error: Cannot find module 'reflect-metadata'

Solution:

  1. Install reflect-metadata dependency
    yarn add reflect-metadata
  2. Import the library in your code
    import "reflect-metadata";

Function deserialize

Hi

I have found several "problems" related with the function deserialize:

1. If you want to deserialize to a DTO, you should initialize all properties of the object. That is:

class SimpleRoster {
    private name: String;
    private worksOnWeekend: Boolean;
}

It doesn't work correctly, you should to include default values in all properties:

class SimpleRoster {
    private name: String = undefined;
    private worksOnWeekend: Boolean = undefined;
}

2. It is not possible to work with your "custom constructor":

export class InvoiceDetail {
  constructor (private concept: string, private numberOfItems: number
              ,private cost: number) {}
}

export class Invoice {
  constructor (private identifier: string, private month: number, private year: number
              ,private detail: InvoiceDetail[]) {}
}

Reading the definition of the ObjectMapper.deserialize, this function only works with objects that have an "empty constructor" however, in this case, it implies that I should include "a lot of" boilerplate code.

Is there an option and/or way to deserialize a json string into objects of those classes (or similar classes) without to remove current constructors? (not always the "source" of those objects will be a Json string).

Thanks in advance

Cannot use objects with an existing constructor?

interface Result {
	success: boolean;
	message: string;
	result: {} | {}[];
}

class ResultData implements Result {
	// success: boolean;
	// message: string;
	// result: {} | {}[];
	constructor(public success: boolean, public message: string, public result: {} | {}[]) {}
}

But I get a compile error because you expect a constructor() {} to be available.

Argument of type 'typeof ResultData' is not assignable to parameter of type 'new () => ResultData'.

I guess one could argue that I don't need an interface for my data classes.

[Question/Feat Request]Mapping multiple JSON properties to one object property

Mapping multiple JSON properties to one object property

For example I have the following JSON object:
obj = { id: '002', date: '05/07/1991', time:'22:35'
And I want to map it to the following class :
class Example { @JsonProperty() id = ''; datetime: Date = new Date(); }
I want to concatenate date and time to datetime. Ho would I go about acomplishing this?

Only Deserializing 2 Levels Deep

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?

Add @JsonIgnore (or similar functionality)

Hi

Sometimes it is necessary to include in the model (DTO in this case), several properties that you don't want to serialize and/or deserialize, so it would be nice add this functionality to this library.

Thanks in advance

Compatibility With Node

Hi,

Awesome work here, pretty much similar to Java jakson library.

One quick question, at this point does this module supported on Node? . I think ES6 features being used here, so just want to check on this. Please share your thoughts

Computed Properties in mapper

Is it possible to have a computed property or maybe multiple names/alias as part of the json mapper ?
Eg. Transformation

[{"id" : "someId"}, {"_id" : "sdfdf"}] => [{"id" : "someId"}, {"id" : "sdfdf"}]

Above I have 2 objects one with id and another with _id want to map both to id in the resulting object
Also the cases file fullname = firstName + secondName

NoAnnotationError while using ObjectMapper in Angular 2 app

Hi,

I'm trying to use the json-object-mapper library in my Angular2 app. I have installed it via npm and my component is defined as below:

import { ObjectMapper } from 'json-object-mapper';
import { Item } from './../../models/item.model';
import { Component, OnInit,Inject } from '@angular/core';

@Component({
  selector: 'app-results-content',
  templateUrl: './results-content.component.html',
  styleUrls: ['./results-content.component.css']
})
export class ResultsContentComponent implements OnInit {

  constructor() { }

  ngOnInit() {

   let json =  {
          "Result": null, 
          "ResultId" : 2041, 
          "AnnotationText" : "hould",       
          "Confidence" : "0.4"
        };
   let testInstance: Item = ObjectMapper.deserialize(Item, json);
      }

}

When I try to run the app, I keep getting an error like : "NoAnnotationError" Error: Cannot resolve all parameters for 'Parser'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'Parser' is decorated with Injectable.

What can I do to resolve this?

My Item class is as below:

import {JsonProperty} from 'json-object-mapper';

export class Item {

    @JsonProperty('Result')
    result: string;

    @JsonProperty('ResultId')
    resultId: number;

    @JsonProperty('AnnotationText')
    annotationText: string;

     @JsonProperty('Confidence')
    confidence:string;
}

Serialize Array empty

api = {
propy:"test",
array:[
{
atr:"hello"
},
{
atr:"hi"
}
]
}

deserialize = ObjectMapper.deserialize(MyClass, api)
console.log(deserialize);

returns =>

{
propy:"test",
array:[
{},
{}
]
}

Getter property serialization

It looks like it is not serializing getters.
The code below does not serialize the getter property.

export class ProjectModule extends ProjectBase {
  @JsonProperty({ name: "t" })
  public get ProjectType(): ProjectType {
    return ProjectType.Module;
  }
}

It only works with the code like this.

export class ProjectModule extends ProjectBase {
  @JsonProperty({ name: "t" })
  public readonly ProjectType: ProjectType = ProjectType.Module;
}

Any plan to implement getters and setters de/serialization?

[question] How to deserialize json-object to an array of a type?

I try deserialize my json-object like this

    return this.http.get(url, { search: params })
        .map(response => <Event[]>ObjectMapper.deserialize(Event[], response.json()));

but the follow error message has been thrown by webpack

You may need an appropriate loader to handle this file type.
| return this.http.get(url, { search: params })
| .map(function (response) { return json_object_mapper_1.ObjectMapper.deserialize(event_class_1.Event[], response.json()); });
| };
| return StageService;

Is it not possible, or what i doing wrong?

Unexpected token import

I am replicating the example class from the wiki page:
import {JsonProperty} from 'json-object-mapper';
export class SimpleRoster {
private worksOnWeekend: Boolean = undefined;
@JsonProperty({type: Date})
private systemDate: Date = undefined;
public isAvailableToday(): Boolean {
if (this.systemDate.getDay() % 6 === 0 && this.worksOnWeekend === false) {
return false;
}
return true;
}

}
but i get this:
.../node_modules\json-object-mapper\dist\ObjectMapper.es2015.js:1
(function (exports, require, module, __filename, __dirname) { import 'reflect-metadata';

is this the correct way?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.