Advertisement
Guest User

Untitled

a guest
Apr 28th, 2017
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. # Typescript class transformer
  2.  
  3. Typescript nam prinása mnoho výhod. Jedna z nich je EcmaScript6 class. Je to elegantné riešenie pre implementáciu modelov v MVC frameworkoch. Pre bežnú komunikáciu medzi aplikáciou a serverom sa často používa JSON format, ktory je skratkou pre JavaScript Object Notation. Tu nastáva problem, JSON je len dátová štruktúra, nie instancia triedy. Čiže ked na backende zavoláme JSON.stringify tak sa instancia triedy zmení na retazec zakódovaného JSON objektu a všetky naše metódy a typy sa stratia. Ako teda naše typy a metódy obnovíme ked znova zavoláme JSON.parse ? Použijeme node modul class-transformer. Funguje ako na frontende tak aj na backende. Tento modul obsahuje sadu dekorátorov a funkcií, ktoré sa o to postarajú.
  4.  
  5. ## Ako na to
  6.  
  7. Samozrejme si package nainstalujeme cez náś obľúbený package manager.
  8. ```yarn add class-transformer``` alebo ```npm install --save class-transformer```
  9.  
  10. Vytvoríme si jednoduchú triedu na ktorej si to odskúšame.
  11.  
  12. ```typescript
  13. class Human{
  14.  
  15. firstname: string;
  16. surname: string;
  17.  
  18. public fullname() {
  19. return this.firstname + ' ' + this.surname;
  20. }
  21.  
  22. }
  23.  
  24. let human = Human();
  25. human.firstname = 'John';
  26. human.surname = 'Doe';
  27. ```
  28. Teraz spravíme z instancie reťazec vo formáte JSON.
  29. ```typescript
  30. let json = JSON.stringify(human);
  31. console.log(json) // -> "{"firstname": "John", "surname": "Doe"}"
  32. ```
  33. Ked použijeme JSON.parse tak nedostaneme instanciu ale iba javascript objekt a naša snaha o zavolanie metódy nam vráti error
  34. ```typescript
  35. let obj = JSON.parse(json);
  36. console.log(obj.fullname()) -> // TypeError : obj.fullname is not a function
  37. ```
  38. Preto použijeme class-transformer ktory znovu vytvorí instanciu triedy Human.
  39. ```typescript
  40. import {plainToClass} from 'class-transformer';
  41. ...
  42.  
  43. let obj = JSON.parse(json);
  44. let human = plainToClass(Human, obj);
  45. console.log(human.fullname()) // -> "John Doe"
  46. ```
  47. Čo sa ale stane ked máme do seba vnorené 2 instancie tried? Použijeme dekorátor ```@Type(() => class)```. Plaintoclass funkcia funguje rekurzívne a zo všetkých dekorovaných vlastností vytvorí instancie.
  48.  
  49. ```typescript
  50. import {Type} from 'class-transformer';
  51.  
  52. class Dog {
  53.  
  54. name: string = void 0;
  55. public bark() {
  56. return this.name + ': Bork!';
  57. }
  58.  
  59. }
  60.  
  61. class Human{
  62.  
  63. firstname: string;
  64. surname: string;
  65.  
  66. @Type(() => Dog)
  67. bestfriend: Dog;
  68.  
  69. public fullname() {
  70. return this.firstname + ' ' + this.surname;
  71. }
  72.  
  73. }
  74.  
  75. let human = JSON.parse('{"firstname": "John", "secondname": "Doe", "bestFriend": {"name": "Jack the dog"}}');
  76. human = plainToClass(Human, human);
  77. console.log(human.bestFriend.bark()) // -> "Jack the dog: Bork!"
  78. ```
  79. V databáze máme uložený zoznam užívateľov a kazdý obsahuje email, meno a heslo. Chceme zoznam užívateľov zobraziť v tabulke niekde na frontende a nechceme samozrejme posielat heslo.
  80. ```typescript
  81. import {Exclude} from 'class-transformer';
  82.  
  83. class User{
  84.  
  85. name: string;
  86. email: string;
  87.  
  88. @Exclude({toPlainOnly: true})
  89. password: string;
  90.  
  91. }
  92. ```
  93. Teraz ked vieme využiť silu dekorátorov a class-transformeru pouzijeme ďalší modul, class-validator (Je to modul od rovnakeho autora), ktorý bude validovat vstup od užívateľa. Napríklad pri registrácii.
  94.  
  95. ```typescript
  96. class User {
  97.  
  98. // nechceme aby user posielal id takže ho vyradíme
  99. @Exclude()
  100. _id: string = void 0;
  101.  
  102. // použijeme 2 dekorátory class-validatoru ktoré skontrolujú či vlastnost nie je prázdna a je to string
  103. // pre správne fungovanie class-validatoru musíme nastaviť defaultnu hodnotu vlastnosti na "void 0", pretože
  104. // typescript transpiler ho nezahrnie v transpilovanej triede a validátor ho nerozpozná
  105. @IsNotEmpty()
  106. @IsString()
  107. firstname: string = void 0;
  108.  
  109. @IsNotEmpty()
  110. @IsString()
  111. surname: string = void 0;
  112.  
  113. // ďalši dekorátor class-validatoru skontroluje či je vlastnosť email
  114. @IsNotEmpty()
  115. @IsEmail()
  116. email: string = void 0;
  117.  
  118. // samozrejme nechceme posielať heslo na frontend ale chceme aby ho užívateľ poslal na backend
  119. @Exclude({toPlainOnly: true})
  120. @IsNotEmpty()
  121. password: string = void 0;
  122.  
  123. // id chceme poslat na frontend a zmeniť jeho kľúč z "_id" na id
  124. @Expose({name: 'id'})
  125. get id() {
  126. return this._id;
  127. }
  128.  
  129. public async genPassword() {}
  130.  
  131. }
  132. ```
  133.  
  134. ```typescript
  135. // funkcia používa async/await
  136. public async register(data) {
  137.  
  138. // vytvorí instanciu z javascript objektu
  139. let user = plainToClass(User, data);
  140.  
  141. // skontroluje či užívateľ vyplnil všetko správne (funckia je asynchrónna čize očakávame promise)
  142. let errors = await validate(user);
  143.  
  144. // ak pri validácii nastal problém funkcia vyhodé error
  145. if(errors.length > 0){
  146. throw new Error(RegisterErrorStatus.WRONG_DATA);
  147. }
  148.  
  149. // skontroluje či užívateľ existuje v databázi
  150. if (await this.userExists(user)) {
  151. throw new Error(RegisterErrorStatus.USER_EXISTS);
  152. }
  153.  
  154. // vygeneruje heslo, použije na to metódu triedy User
  155. await user.genPassword();
  156.  
  157. // vloží do databáze
  158. this.db.insert(User, user);
  159.  
  160. }
  161. ```
  162. S použitím class-transformeru, class-validatoru a async/await je zápis funkcie velmi elegantný a pocit z písania backendu v typescripte príjemný.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement