Giter VIP home page Giter VIP logo

ta-json's People

Contributors

edcarroll 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ta-json's Issues

Simple converters for serialize and deserialize

For simple converters, creating an IPropertyConverter seems a bit overkill. It would be nice to specify a function as part of a decorator for serialization or deserialization.

For example:

@JsonProperty('wifi_signal')
@JsonDeserailizer((value) => !value ? 0 : value * 20)
public wifiSignalStrength: number
@JsonProperty('wifi_signal')
@JsonSerializer((value) => !value ? 0 : value / 20)
public wifiSignalStrength: number

Thoughts?

Cheers,

  • Joe

Optional vs. mandatory JSON properties during serialization and de-serialization

Go lang's JSON (un)marshal-er includes a handy omitempty "annotation" for struct fields:
https://golang.org/pkg/encoding/json/
"The 'omitempty' option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string."

There is a similar default behaviour in ta-json, during serialization to JSON:
https://github.com/edcarroll/ta-json/blob/master/lib/methods/serialize.ts#L33

if ((value === null || value === undefined) || p.writeonly) {
   return;
}

...as well as during deserialization from JSON:
https://github.com/edcarroll/ta-json/blob/master/lib/methods/deserialize.ts#L41

if ((value === null || value === undefined) || p.readonly) {
    return;
}

So, I have been wondering whether an additional @JsonRequired() decoration could be useful for class members (or conversely: @JsonOptional(), but this would require changing the current default behaviour). In case of an "empty" value (to be clarified, perhaps not exactly the same definition as Go lang), a property would not be outputted to JSON, and deserialization may "fail" if the property is actually required ("failure" may be an error callback where the API consumer could act accordingly).

...which also brings the question of TypeScript's strictNullChecks and the ? question mark to denote optionality:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html

Thoughts welcome :)

is extending JSON a good idea?

Today I've checked many similar libraries but none of them extends JSON, instead, they offer some new static methods for transformation. Extending JSON does not sound like a good idea, why did you prefer such a way?

serialize method don't change the properties

Hi!

I'm trying to serialize the following object:

@JsonObject()
export class Resale {
 
    @JsonProperty('codigo')
    code?: string;

}

Calling TaJson.serialize(resale) gives the following result:

{
    "code":"123"
}

How can I serialize the object to result in the following string?

 const resale: ResaleUpdate = {
        code: '123',
 };

Expected result:

{
    "codigo":"123"
}

I was thinking that serialization will use the value provided in the JsonProperty decorator. Is this right?

Thanks!

Problem serializing arrays

Loving this library! Using it loads, just awesome.

I want to serialize an array as a single string:

@JsonProperty()
@JsonElementType(Joint)
public joints: Joint[];

I want a single string, not an array of strings.

I couldn't see a way of doing this, so I had to create my own class JointArray with push/splice methods and then implement a JointArrayConverter. Works but a bit long winded.

It would be nice to be able to specify a custom converter for an array, or even just a pre-serialization method on the parent class.

Cheers,
Paul

Use of interfaces

Does the library support using an interface type within a class? Say my class User has a property "animal" of type Animal, which is an interface? I didnt figure out how I can do that. It seems like I cannot use @jsontype(Animal)

Map Support

I see you support Arrays and Sets, do you support Maps? I'm having some issues with them, and I don't see anything in the documentation.

Thanks.

TypeScript Constructors are erased unless explicitly called - parsing fails

I have successfully used your framework to build a service but i am facing an issue. I have an entity class that I do not instanceiate any where in the code - it is only created by calls to TaJson.parse(). While can understand why tsc erases the constructor function - since it is not explicitly called - I wonder if there is a clever way to prevent it from being erased? The only ways i can come up with is to either create a dummy instance somewhere or to export a function that calls the constructor. Both feels a bit "hackish".

Ideas?

deserialize does not return model

Hi, I don't know If I am fool but deserializing does not resolve an instance of my class. The test below fails

import { AccountDoc } from '../model/doc/account-doc';
import { expect } from 'chai';
import { JSON as TA } from "ta-json";

describe('Class Validation', () => {
    it('should build Account class', () => {
        let body = { fullName: "Mustafa Ekim", email: "[email protected]", password: "xxx" };
        let account = TA.deserialize<AccountDoc>(body, AccountDoc);
        expect(account.hi()).to.be.equal("That's Mustafa Ekim");
        expect(account instanceof AccountDoc).to.equal(true);
    });
});

TypeError: account.hi is not a function
AssertionError: expected false to equal true

@JsonConverter with number

Is it really possible to use the converter with a string as shown in your example?
I'm asking because of these lines:

const primitive = definition.type === String || definition.type === Boolean || definition.type === Number;

and

   if (!primitive) {
        const converter = definition.converter || propertyConverters.get(definition.type);
        const objDefinition = objectDefinitions.get(definition.type);

        if (converter) {
            return converter.deserialize(value);
        }

        if (objDefinition) {
            return deserialize(value, definition.type);
        }
    }

In my case the type is a number and as a result primitive is true and the converter never executed.
The ReverseStringConverter is used without a 'new' in the example. Is that correct?

Cannot serialize property without type

When I try the quickstart using Typescript 2.6.1 I get this error:

    Cannot serialize property 'firstName' without type!

      at node_modules/ta-json/src/methods/serialize.ts:30:23
          at Map.forEach (<anonymous>)
      at node_modules/ta-json/src/methods/serialize.ts:28:22
          at Array.forEach (<anonymous>)
      at serializeRootObject (node_modules/ta-json/src/methods/serialize.ts:27:17)
      at Object.serialize (node_modules/ta-json/src/methods/serialize.ts:11:12)
      at Function.Object.<anonymous>.JSON.serialize (node_modules/ta-json/src/json.ts:15:16)
      at Function.Object.<anonymous>.JSON.stringify (node_modules/ta-json/src/json.ts:19:43)

I can make the error go away by adding @JsonElementType(String) below each of the @JsonProperty() decorators. I don't think this should be necessary though. Is this a bug or some bit of configuration I'm missing?

What are the requirements for "JsonDiscriminatorProperty" and "JsonDiscriminatorValue"?

I would like to serialize and deserialize multiple instances of a common interface. To do this, the README says I should use JsonDiscriminatorProperty and JsonDiscriminatorValue. However, it doesn't say what these actually do, or what the requirements are for using these decorators, so I will ask here:

Is it required that my superclass/interface has a property that describes the subclass type? For example, the Animal type in the example has a type:AnimalType field (pointed to by the JsonDiscriminatorProperty decorator). Is this required for (de)serialization to work?

In other words:

  1. Do I have to create a distinct value (e.g. via an enum) for all the subtypes of the interface/superclass I want to serialize?
  2. Do all instances need a property that is set to this value?

Deserialize a null value in a list

Great library!

If I deserialize an array with a null value, I have an error

Uncaught TypeError: Cannot read property 'id' of null
    at eval (deserialize.js:32)

Could you check value before deserialize it ?

Maybe like this

function deserializeObject(object, definition, options) {
	var primitive = definition.type === String || definition.type === Boolean || definition.type === Number;
	var value = object;

	if(value != null)
	{
		var converter = definition.converter || propertyConverters.get(definition.type);
		if (converter) {
			return converter.deserialize(value);
		}
		if (!primitive) {
			var objDefinition = objectDefinitions.get(definition.type);
			if (objDefinition) {
				return deserialize(value, definition.type);
			}
		}
	}

	return value;
}

Thank you

Constructor is not called

Hi, it seems like while deserializing, the constructor is never called. Is that the expected behavior? To me, that sounds very odd. The abstract class BaseDoc has a @JsonProperty declared, but the property is not set.

AccountDoc

import { BaseDoc } from "./base-doc";
import { JsonObject, JsonProperty } from "ta-json";

@JsonObject()
export class AccountDoc extends BaseDoc {

    @JsonProperty() fullName: string;
    @JsonProperty() email: string;
    @JsonProperty() password: string;

    constructor() {
        super("AccountDoc");
    }
}

BaseDoc

import { ObjectID } from "mongodb";
import { JsonProperty } from "ta-json";

export abstract class BaseDoc {

    @JsonProperty() private collectionName: string;
    
    _id: ObjectID;

    constructor(collectionName: string) {
        this.collectionName = collectionName;
    }

    public getId(): string { return this._id.toHexString(); }
    public get_id(): ObjectID { return this._id; }
    public getCollectionName(): string { return this.collectionName; }
    public setCollectionName(value: string) { this.collectionName = value; }
}

Test case

    it('should build AccountDoc class', () => {
        let body = { "fullName": "Mustafa Ekim", "email": "[email protected]", "password": "xxx" };
        let accountDoc: AccountDoc = TA.deserialize<AccountDoc>(body as any, AccountDoc);
        console.dir(accountDoc);
        expect(accountDoc.getCollectionName()).to.equal("AccountDoc");
        expect(accountDoc.fullName).to.be.equal("Mustafa Ekim");
        expect(accountDoc instanceof AccountDoc).to.equal(true);
    });

the collectionName property is never set.

AssertionError: expected undefined to equal 'AccountDoc'

Typescript Class to Object

Hi, is it possible to transform an instance of a TypeScript class to an instance of Object type?

I know that I can achieve this by first stringifying and then parsing as Object however I wonder if there is a direct method for that.

(Why I need that? Because I want to persist my User into mongoDB with JsonDiscriminatorValues.)

Thanks!

@JsonConstructor only invoked with JSON.deserialize(), not JSON.parse() (both use runConstructor: true)

To reproduce:

import {
    BeforeDeserialized, JsonConstructor, JsonElementType,
    JsonObject, JsonProperty, JSON, OnDeserialized,
} from "ta-json";

@JsonObject()
class Clazz {

    @JsonProperty()
    public foo: string;

    @JsonConstructor()
    private _JsonConstructor() {
        console.log("_JsonConstructor");
    }
}

console.log("===============");
console.log("===============");

let jsonObj = { foo: "bar" };
JSON.deserialize<Clazz>(jsonObj, Clazz, { runConstructor: true });

console.log("---------------");

let jsonString = '{"foo":"bar"}';
JSON.parse<Clazz>(jsonString, Clazz, { runConstructor: true });

console.log("===============");
console.log("===============");

using in WebWorker

I use this library in angular's webworker, I have an error, because in webworker, window is not accessible :

Uncaught ReferenceError: Buffer is not defined
    at eval (converter.js:10)

Could you check nodeJS's environment otherwise ?

Maybe with this

var isNode=new Function("try {return this===global;}catch(e){return false;}");

Thank you

Problem when using with Angular

Hi,

I was using the library on nodejs and everything was working as expected. Now I try to do the same thing on angular (with webpack) and somehow the library just breaks everything. I cannot see the real error but wherever I load the JSON (from "ta-json") Angular fails to load the whole file.

Uncaught Error: Unexpected value 'AppComponent' declared by the module 'AppModule'

I am getting the error above but I tried and tested many times that it only occurs if I use a simple JSON.deserialize or any other method it provides.

Any idea?

Passing Object instead of String

I didnt observe any method that takes an object and cast to a typed TypeScript object. Should we always pass a string? It seems like I should wrap the js object with JSON.stringify(json) everytime.

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.