@@ -13,72 +13,7 @@ Also it allows to serialize / deserialize object based on criteria.
13
13
This tool is super useful on both frontend and backend.
14
14
15
15
Example how to use with angular 2 in [ plunker] ( http://plnkr.co/edit/Mja1ZYAjVySWASMHVB9R ) .
16
- Source code is [ here] ( https://github.com/pleerock/class-transformer-demo ) .
17
-
18
- ## Installation
19
-
20
- ### Node.js
21
-
22
- 1 . Install module:
23
-
24
- ` npm install class-transformer --save `
25
-
26
- 2 . ` reflect-metadata ` shim is required, install it too:
27
-
28
- ` npm install reflect-metadata --save `
29
-
30
- and make sure to import it in a global place, like app.ts:
31
-
32
- ``` typescript
33
- import " reflect-metadata" ;
34
- ```
35
-
36
- 3. ES6 features are used , if you are using old version of node .js you may need to install es6 - shim :
37
-
38
- ` npm install es6-shim --save `
39
-
40
- and import it in a global place like app .ts :
41
-
42
- ` ` ` typescript
43
- import "es6-shim";
44
- ` ` `
45
-
46
- ### Browser
47
-
48
- 1. Install module :
49
-
50
- ` npm install class-transformer --save `
51
-
52
- 2. ` reflect-metadata ` shim is required , install it too :
53
-
54
- ` npm install reflect-metadata --save `
55
-
56
- add ` <script> ` to reflect -metadata in the head of your ` index.html ` :
57
-
58
- ` ` ` html
59
- <html>
60
- <head>
61
- <!-- ... -->
62
- <script src="node_modules/reflect-metadata/Reflect.js"></script>
63
- </head>
64
- <!-- ... -->
65
- </html>
66
- ` ` `
67
-
68
- If you are using angular 2 you should already have this shim installed .
69
-
70
- 3. If you are using system .js you may want to add this into ` map ` and ` package ` config :
71
-
72
- ` ` ` json
73
- {
74
- "map": {
75
- "class-transformer": "node_modules/class-transformer"
76
- },
77
- "packages": {
78
- "class-transformer": { "main": "index.js", "defaultExtension": "js" }
79
- }
80
- }
81
- ` ` `
16
+ Source code is available [ here] ( https://github.com/pleerock/class-transformer-demo ) .
82
17
83
18
## What is class-transformer
84
19
@@ -95,8 +30,8 @@ Usually you define them via `class` notation.
95
30
So, what is the problem?
96
31
97
32
Sometimes you want to transform plain javascript object to the ES6 ** classes** you have.
98
- For example , if you are loading a json from your backend , some api or from a json file .
99
- After you ` JSON.parse ` it you have a plain javascript object , not instance of class you have .
33
+ For example, if you are loading a json from your backend, some api or from a json file,
34
+ and after you ` JSON.parse ` it you have a plain javascript object, not instance of class you have.
100
35
101
36
For example you have a list of users in your ` users.json ` that you are loading:
102
37
@@ -144,58 +79,138 @@ following code:
144
79
145
80
``` typescript
146
81
fetch (" users.json" ).then ((users : User []) => {
147
- // here you can use users[0].id, you can also use users[0].firstName and users[0].lastName
148
- // however you cannot use users[0].getName() or users[0].isAdult() because "users" actually is
149
- // array of plain javascript objects, not instances of User object.
150
- // You actually lied to compiler when you said that `users: User[]`.
82
+ // you can use users here, and type hinting also will be available to you,
83
+ // but users are not actually instances of User class
84
+ // this means that you can't use methods of User class
151
85
});
152
86
```
153
87
88
+ In this code you can use ` users[0].id ` , you can also use ` users[0].firstName ` and ` users[0].lastName ` .
89
+ However you cannot use ` users[0].getName() ` or ` users[0].isAdult() ` because "users" actually is
90
+ array of plain javascript objects, not instances of User object.
91
+ You actually lied to compiler when you said that its ` users: User[] ` .
92
+
154
93
So what to do? How to make a ` users ` array of instances of ` User ` objects instead of plain javascript objects?
155
94
Solution is to create new instances of User object and manually copy all properties to new objects.
95
+ But things may go wrong very fast once you have a more complex object hierarchy.
156
96
157
- Alternatives? Yes, you can use this library . Purpose of this library is to help you to map you plain javascript
158
- objects to the instances of classes you have created .
97
+ Alternatives? Yes, you can use class-transformer . Purpose of this library is to help you to map you plain javascript
98
+ objects to the instances of classes you have.
159
99
160
100
This library also great for models exposed in your APIs,
161
101
because it provides a great tooling to control what your models are exposing in your API.
102
+ Here is example how it will look like:
103
+
104
+ ``` typescript
105
+ fetch (" users.json" ).then ((users : Object []) => {
106
+ const realUsers = plainToClass (users );
107
+ // now each user in realUsers is instance of User class
108
+ });
109
+ ```
110
+
111
+ Now you can use ` users[0].getName() ` and ` users[0].isAdult() ` methods.
112
+
113
+ ## Installation
114
+
115
+ ### Node.js
116
+
117
+ 1 . Install module:
118
+
119
+ ` npm install class-transformer --save `
120
+
121
+ 2 . ` reflect-metadata ` shim is required, install it too:
122
+
123
+ ` npm install reflect-metadata --save `
124
+
125
+ and make sure to import it in a global place, like app.ts:
126
+
127
+ ``` typescript
128
+ import " reflect-metadata" ;
129
+ ```
130
+
131
+ 3. ES6 features are used , if you are using old version of node .js you may need to install es6 - shim :
132
+
133
+ ` npm install es6-shim --save `
134
+
135
+ and import it in a global place like app .ts :
136
+
137
+ ` ` ` typescript
138
+ import "es6-shim";
139
+ ` ` `
140
+
141
+ ### Browser
142
+
143
+ 1. Install module :
144
+
145
+ ` npm install class-transformer --save `
146
+
147
+ 2. ` reflect-metadata ` shim is required , install it too :
148
+
149
+ ` npm install reflect-metadata --save `
150
+
151
+ add ` <script> ` to reflect -metadata in the head of your ` index.html ` :
152
+
153
+ ` ` ` html
154
+ <html>
155
+ <head>
156
+ <!-- ... -->
157
+ <script src="node_modules/reflect-metadata/Reflect.js"></script>
158
+ </head>
159
+ <!-- ... -->
160
+ </html>
161
+ ` ` `
162
+
163
+ If you are using angular 2 you should already have this shim installed .
164
+
165
+ 3. If you are using system .js you may want to add this into ` map ` and ` package ` config :
166
+
167
+ ` ` ` json
168
+ {
169
+ "map": {
170
+ "class-transformer": "node_modules/class-transformer"
171
+ },
172
+ "packages": {
173
+ "class-transformer": { "main": "index.js", "defaultExtension": "js" }
174
+ }
175
+ }
176
+ ` ` `
162
177
163
178
### Methods
164
179
165
180
#### plainToClass
166
181
182
+ This method transforms a plain javascript object to instance of specific class .
183
+
167
184
` ` ` typescript
168
185
import {plainToClass} from "class-transformer";
169
186
170
187
let users = plainToClass(User, userJson); // to convert user plain object a single user. also supports arrays
171
188
` ` `
172
189
173
- This allows to map plain javascript array ` usersJson ` to array of ` User ` objects.
174
- Now you can use ` users[0].getName() ` and ` users[0].isAdult() ` methods.
175
-
176
190
#### classToPlain
177
191
192
+ This method transforms your class object back to plain javascript object , that can be ` JSON.stringify ` later .
193
+
178
194
` ` ` typescript
179
195
import {classToPlain} from "class-transformer";
180
196
let photo = classToPlain(photo);
181
197
` ` `
182
198
183
- This method transforms your class object back to plain javascript object, that can be ` JSON.stringify ` later.
184
-
185
199
#### classToClass
186
200
201
+ This method transforms your class object into new instance of the class object .
202
+ This maybe treated as deep clone of your objects .
203
+
187
204
` ` ` typescript
188
205
import {classToClass} from "class-transformer";
189
206
let photo = classToClass(photo);
190
207
` ` `
191
208
192
- This method transforms your class object into new instance of the class object.
193
- This maybe treated as deep clone of your objects.
194
209
You can also use a ` ignoreDecorators ` option in transformation options to ignore all decorators you classes is using .
195
210
196
211
#### serialize
197
212
198
- You can serialize your model to right json using ` serialize ` method:
213
+ You can serialize your model right to the json using ` serialize ` method :
199
214
200
215
` ` ` typescript
201
216
import {serialize} from "class-transformer";
@@ -206,7 +221,7 @@ let photo = serialize(photo);
206
221
207
222
#### deserialize and deserializeArray
208
223
209
- You can deserialize your model to from json using ` deserialize ` method:
224
+ You can deserialize your model to from a json using ` deserialize ` method :
210
225
211
226
` ` ` typescript
212
227
import {deserialize} from "class-transformer";
@@ -228,7 +243,8 @@ Since Typescript does not have good reflection abilities yet,
228
243
we should implicitly specify what type of object each property contain.
229
244
This is done using `@Type` decorator.
230
245
231
- Lets say we have an album with photos. And we are trying to convert album plain object to class object:
246
+ Lets say we have an album with photos .
247
+ And we are trying to convert album plain object to class object :
232
248
233
249
```typescript
234
250
import {Type, plainToClass} from " class-transformer" ;
@@ -254,7 +270,7 @@ let album = plainToClass(Album, albumJson);
254
270
255
271
### Exposing getters and method return values
256
272
257
- You can expose what you getter or method return by setting a ` @Expose() ` decorator to those getters or methods:
273
+ You can expose what your getter or method return by setting a ` @Expose() ` decorator to those getters or methods:
258
274
259
275
``` typescript
260
276
import {Expose } from " class-transformer" ;
@@ -280,7 +296,7 @@ export class User {
280
296
281
297
### Exposing properties with different names
282
298
283
- If you want to expose some of properties with different names ,
299
+ If you want to expose some of properties with a different name ,
284
300
you can do it by specifying a ` name ` option to ` @Expose ` decorator:
285
301
286
302
``` typescript
@@ -378,8 +394,8 @@ In this case you don't need to `@Exclude()` a whole class.
378
394
379
395
### Skipping private properties, or some prefixed properties
380
396
381
- If you name your private properties with a prefix, lets say with ` _ ` , then you can exclude such properties
382
- from transformation too:
397
+ If you name your private properties with a prefix, lets say with ` _ ` ,
398
+ then you can exclude such properties from transformation too:
383
399
384
400
``` typescript
385
401
import {classToPlain } from " class-transformer" ;
@@ -388,6 +404,39 @@ let photo = classToPlain(photo, { excludePrefixes: ["_"] });
388
404
389
405
This will skip all properties that start with ` _ ` prefix.
390
406
You can pass any number of prefixes and all properties that begin with these prefixes will be ignored.
407
+ For example:
408
+
409
+ ``` typescript
410
+ import {Expose } from " class-transformer" ;
411
+
412
+ export class User {
413
+
414
+ id: number ;
415
+ private _firstName: string ;
416
+ private _lastName: string ;
417
+ _password: string ;
418
+
419
+ setName(firstName : string , lastName : string ) {
420
+ this ._firstName = firstName ;
421
+ this ._lastName = lastName ;
422
+ }
423
+
424
+ @Expose ()
425
+ get name() {
426
+ return this .firstName + " " + this .lastName ;
427
+ }
428
+
429
+ }
430
+
431
+ const user = new User ();
432
+ user .id = 1 ;
433
+ user .setName (" Johny" , " Cage" );
434
+ user ._password = 123 ;
435
+
436
+ const plainUser = classToPlain (user , { excludePrefixes: [" _" ] });
437
+ // here plainUser will be equal to
438
+ // { id: 1, name: "Johny Cage" }
439
+ ```
391
440
392
441
### Using groups to control excluded properties
393
442
@@ -442,11 +491,11 @@ export class User {
442
491
443
492
``` typescript
444
493
import {classToPlain } from " class-transformer" ;
445
- let user1 = classToPlain (user , { 0.5 }); // will contain id and name
446
- let user2 = classToPlain (user , { 0.7 }); // will contain id, name and email
447
- let user3 = classToPlain (user , { 1 }); // will contain id and name
448
- let user4 = classToPlain (user , { 2 }); // will contain id and name
449
- let user5 = classToPlain (user , { 2.1 }); // will contain id, name nad password
494
+ let user1 = classToPlain (user , { version: 0.5 }); // will contain id and name
495
+ let user2 = classToPlain (user , { version: 0.7 }); // will contain id, name and email
496
+ let user3 = classToPlain (user , { version: 1 }); // will contain id and name
497
+ let user4 = classToPlain (user , { version: 2 }); // will contain id and name
498
+ let user5 = classToPlain (user , { version: 2.1 }); // will contain id, name nad password
450
499
```
451
500
452
501
### Сonverting date strings into Date objects
@@ -543,7 +592,7 @@ it will convert a date value in your photo object to moment date.
543
592
544
593
### Working with generics
545
594
546
- Generics are not supported because TypeScript does not have good reflection abilities.
595
+ Generics are not supported because TypeScript does not have good reflection abilities yet .
547
596
Once TypeScript team provide us better runtime type reelection tools, generics will be implemented.
548
597
There are some tweaks however you can use, that maybe can solve your problem.
549
598
[ Checkout this example.] ( https://github.com/pleerock/class-transformer/tree/master/sample/sample4-generics )
@@ -582,7 +631,6 @@ Source code is [here](https://github.com/pleerock/class-transformer-demo).
582
631
Take a look on samples in [ ./sample] ( https://github.com/pleerock/class-transformer/tree/master/sample ) for more examples of
583
632
usages.
584
633
585
-
586
634
## Release notes
587
635
588
636
See information about breaking changes and release notes [ here] ( https://github.com/pleerock/class-transformer/tree/master/doc/release-notes.md ) .
0 commit comments