-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path395.c72937b30860fcf7.js
1 lines (1 loc) · 26.4 KB
/
395.c72937b30860fcf7.js
1
"use strict";(self.webpackChunkbase_test=self.webpackChunkbase_test||[]).push([[395],{5395:(f,c,i)=>{i.r(c),i.d(c,{EntityMappingModule:()=>E});var p=i(177),l=i(483),o=i(8550),e=i(4438),r=i(6377);function d(t,j){if(1&t&&(e.j41(0,"tr")(1,"td")(2,"span",6),e.EFF(3),e.j41(4,"a",7),e.nrm(5,"i",8),e.k0s()()(),e.j41(6,"td")(7,"span",9),e.EFF(8),e.k0s()(),e.j41(9,"td")(10,"span",10),e.EFF(11),e.k0s()(),e.j41(12,"td")(13,"span",11),e.EFF(14),e.k0s()(),e.j41(15,"td")(16,"span",12),e.EFF(17),e.k0s()(),e.j41(18,"td")(19,"span",13)(20,"pre"),e.nrm(21,"code",3),e.k0s()()()()),2&t){const a=j.$implicit;e.R7$(3),e.JRh(a.name),e.R7$(5),e.JRh(a.usage),e.R7$(3),e.JRh(a.attributes),e.R7$(3),e.JRh(a.description),e.R7$(3),e.JRh(a.other),e.R7$(4),e.Y8G("highlight",a.example)}}const g=l.iI.forChild([{path:"",component:(()=>{class t extends o.PJ{constructor(){super(),this.easyRestCode='let data:clazz[] = entityDataService.fetchData<TargetClazz>("http://server:8000/rest/fetch/data", true);',this.mavenExampleCode='<plugin>\n <artifactId>maven-antrun-plugin</artifactId>\n <executions>\n <execution>\n <id>replace1</id>\n <phase>generate-resources</phase>\n <configuration>\n <tasks>\n <echo>====================================</echo>\n <echo>= EXECUTING REPLACEMENT TASKS =</echo>\n <echo>====================================</echo>\n <echo>-> Project Base Dir: ${project.basedir}</echo>\n <echo>- Running Array fix on ${project.basedir}/src/app/model/entities</echo>\n <replace token="Array = undefined" value="Array<any> = undefined" dir="${project.basedir}/src/app/model/entities">\n <include name="**/*.ts"/>\n </replace>\n <echo>- Running Bad REST path fix on ${project.basedir}/src/app/model/entities</echo>\n <replace token="/rno/referencedata/" value="/rno/backend/referencedata/" dir="${project.basedir}/src/app/model/api">\n <include name="**/*.ts"/>\n </replace>\n <echo>- Running 2nd Bad REST path fix on ${project.basedir}/src/app/model/entities</echo>\n <replace token="/rno/obe/" value="/rno/backend/obe/" dir="${project.basedir}/src/app/model/api">\n <include name="**/*.ts"/>\n </replace>\n <echo>- Running Primitive Return Type Replacements on ${project.basedir}/src/app/model/entities</echo>\n <replace token="), boolean, \'boolean\'); // RETURN-TYPE-MARKER" value="), undefined, \'boolean\'); // RETURN-TYPE-MARKER" dir="${project.basedir}/src/app/model/api">\n <include name="**/*.ts"/>\n </replace>\n <replace token="), string, \'string\'); // RETURN-TYPE-MARKER" value="), undefined, \'string\'); // RETURN-TYPE-MARKER" dir="${project.basedir}/src/app/model/api">\n <include name="**/*.ts"/>\n </replace>\n <echo>====================================</echo>\n <echo>Annotation Propagation Task Up Ahead</echo>\n <echo>====================================</echo>\n </tasks>\n </configuration>\n <goals>\n <goal>run</goal>\n </goals>\n </execution>\n </executions>\n</plugin>\n \x3c!-- Inject annotations into all entities that are of type Date, etc --\x3e\n<plugin>\n<groupId>com.google.code.maven-replacer-plugin</groupId>\n<artifactId>replacer</artifactId>\n<version>1.5.3</version>\n<executions>\n <execution>\n <phase>generate-resources</phase>\n <goals>\n <goal>replace</goal>\n </goals>\n </execution>\n</executions>\n<configuration>\n <basedir>${project.basedir}/src/app/model/entities</basedir>\n <includes>\n <include>**/*.ts</include>\n </includes>\n <regexFlags>\n <regexFlag>CASE_INSENSITIVE</regexFlag>\n <regexFlag>MULTILINE</regexFlag>\n </regexFlags>\n <replacements>\n <replacement>\n \x3c!-- annotate all Date properties with @DateProp --\x3e\n <token>((.*: Date) =.*)</token>\n <value>\\@DateProp\\(\\)\n $1\n </value>\n </replacement>\n <replacement>\n \x3c!-- annotate executionTime string with a microseconds prop --\x3e\n <token>((.*\\sexecutionTime: string) =.*)</token>\n <value>\\@StringDateWithMicrosProp\\(\\)\n $1\n </value>\n </replacement>\n <replacement>\n \x3c!-- annotate transactionTime string with a microseconds prop --\x3e\n <token>((.*\\stransactionTime: string) =.*)</token>\n <value>\\@StringDateWithMicrosProp\\(\\)\n $1\n </value>\n </replacement>\n <replacement>\n \x3c!-- replace the type of execution time to MicrosecondDate --\x3e\n <token>\\sexecutionTime: string</token>\n <value>executionTime: MicrosecondDate</value>\n </replacement>\n <replacement>\n \x3c!-- replace the type of transaction time to MicrosecondDate --\x3e\n <token>\\stransactionTime: string</token>\n <value>transactionTime: MicrosecondDate</value>\n </replacement>\n <replacement>\n \x3c!-- Remove bad generation. Enums aren\'t recognized as they\'re declared as types --\x3e\n <token>@ObjectMapping\\(\'.*Enum.*\'\\)</token>\n <value></value>\n </replacement>\n <replacement>\n \x3c!-- Remove bad generation. Array<> ends up in the list --\x3e\n <token>@List\\(\'Array.{4}(.*).{4}\'\\)</token>\n <value>@List(\'$1\')</value>\n </replacement>\n <replacement>\n \x3c!-- MUST BE LAST OR YOU WILL HAVE DOUBLE ANNOTATIONS. Annotate all Time strings with a StringDateProp --\x3e\n <token>((.*Time: string) =.*)</token>\n <value>\\@StringDateProp\\(\\)\n $1\n </value>\n </replacement>\n </replacements>\n</configuration>\n</plugin>',this.currencyMappingCode="let allCurrencies:Currency[] = [];\n\njsonObj.currencies.forEach((ele) => {\n let cur:Currency = null;\n EntityMapper.mapEntityTreeFrom(ele, cur, Currency, entityDataService);\n allCurrencies.push(cur)\n});",this.currencyCode='{\n currencies: [\n { code: "CHF", name: "Swiss Francs" },\n { code: "EUR", name: "Euros" }\n ]\n}',this.goodInitCode="export class {\n name: string = undefined;\n}",this.badInitCode="export class {\n name: string;\n}",this.baseEntityCode='import {BaseEntity} from "@six-group/base-angular-framework/core";\n\nexport class Currency implements BaseEntity<Currency> {\n\n _id: string = null;\n\n name: string = null;\n code: string = null;\n exchangeRateCHF: number = null;\n\n override getClassName(): string {\n return "Currency";\n }\n\n override postProcess() {\n this._id = this.name + this.code;\n }\n}'}getEventGrid(a){}hookObservables(){}ngOnInit(){super.ngOnInit()}ngAfterViewInit(){super.ngAfterViewInit()}ngOnDestroy(){super.ngOnDestroy()}static{this.\u0275fac=function(n){return new(n||t)}}static{this.\u0275cmp=e.VBU({type:t,selectors:[["EntityMappingView"]],features:[e.Jv_([]),e.Vt3],decls:148,vars:12,consts:[["xmlns","http://www.w3.org/1999/html",1,"documentParent"],[1,"document"],[1,"description"],["language","ts",3,"highlight"],[1,"description",2,"color","red"],["language","xml",3,"highlight"]],template:function(n,s){1&n&&(e.j41(0,"div",0)(1,"div",1)(2,"h1"),e.EFF(3,"Entity Mapping"),e.k0s(),e.j41(4,"h2"),e.EFF(5,"The Fast (But Usually Not Good Enough) Way"),e.k0s(),e.j41(6,"p",2),e.EFF(7,"You can cast raw JSON over to an object with just a simple:"),e.k0s(),e.j41(8,"pre"),e.nrm(9,"code",3),e.k0s(),e.j41(10,"p",2),e.EFF(11,"And this is fine for flat JSON structures or simple object graphs where no type conversion needs to be done. If your model is small and simple, this may be the way you want to do it rather than using the "),e.j41(12,"i"),e.EFF(13,"EntityMapper"),e.k0s(),e.EFF(14,". Once you get into complex types and structures, it gets messy and usually requires a lot of custom code."),e.k0s(),e.j41(15,"p",2),e.EFF(16,"By using the "),e.j41(17,"i"),e.EFF(18,"EntityMapper"),e.k0s(),e.EFF(19,' and its associated annotations (see the next section in the menu) you can get away from most of the "having to deal with getting real objects out of JSON" and just get on with your life (or code).'),e.k0s(),e.j41(20,"p",2),e.EFF(21,"The "),e.j41(22,"i"),e.EFF(23,"EntityMapper"),e.k0s(),e.EFF(24,'\'s job is to create real "Entity classes" from raw JSON data. The result is classes that usually match the ones that exist on a server. And with all the nested entities and complex references and type conversion that may need to be done.'),e.k0s(),e.j41(25,"h2"),e.EFF(26,"The Short Version (TL;DR / You've been here before)"),e.k0s(),e.j41(27,"p",2)(28,"i"),e.EFF(29,"Step 1"),e.k0s(),e.EFF(30," - Have your entity class implement "),e.j41(31,"i"),e.EFF(32,"BaseEntity"),e.k0s(),e.EFF(33," per:"),e.k0s(),e.j41(34,"pre"),e.nrm(35,"code",3),e.k0s(),e.nrm(36,"br")(37,"br"),e.j41(38,"p",2)(39,"i"),e.EFF(40,"Step 2"),e.k0s(),e.EFF(41," - When you have your JSON structure that you wish to convert, call:"),e.k0s(),e.j41(42,"pre"),e.nrm(43,"code",3),e.k0s(),e.j41(44,"p",2),e.EFF(45,"And the targetObj will then be of the "),e.j41(46,"i"),e.EFF(47,"EntityClassToMapTo"),e.k0s(),e.EFF(48," type. "),e.nrm(49,"br")(50,"br"),e.EFF(51," If using the "),e.j41(52,"i"),e.EFF(53,"EntityDataService"),e.k0s(),e.EFF(54," all the mapping will be done for you, and you simply use the data fetching methods with the type parameter ("),e.j41(55,"i"),e.EFF(56,"TargetClazz"),e.k0s(),e.EFF(57," in the below example) for the target object such as:"),e.k0s(),e.j41(58,"pre"),e.nrm(59,"code",3),e.k0s(),e.j41(60,"h2"),e.EFF(61,"The Long Version (First time here)"),e.k0s(),e.j41(62,"h3"),e.EFF(63,"The BaseEntity class"),e.k0s(),e.j41(64,"p",2),e.EFF(65,"All your entity classes that you wish to be able to automatically build up with the "),e.j41(66,"i"),e.EFF(67,"EntityMapper"),e.k0s(),e.EFF(68," should implement the "),e.j41(69,"i"),e.EFF(70,"BaseEntity"),e.k0s(),e.EFF(71," interface that contains utility methods that are later used by the "),e.j41(72,"i"),e.EFF(73,"EntityMapper"),e.k0s(),e.EFF(74," to help create the entities."),e.k0s(),e.j41(75,"p",2),e.EFF(76,"Here is a simple example class that extends the BaseEntity and includes a method override that creates a local property called _id after the class has been created by the mapper:"),e.k0s(),e.EFF(77,"> "),e.j41(78,"pre"),e.nrm(79,"code",3),e.k0s(),e.j41(80,"p",2),e.EFF(81,"The example shows the required method overrides. The "),e.j41(82,"i"),e.EFF(83,"getClassName"),e.k0s(),e.EFF(84,' override is used when the code is "javascript minimized"/optimized in a production build, as the class name will then disappear, and with it; any possibility of referencing it as a type.'),e.k0s(),e.j41(85,"h3"),e.EFF(86,"IMPORTANT - EVERY CLASS PROPERTY MUST BE INITIALIZED"),e.k0s(),e.j41(87,"p",2),e.EFF(88,"It's imperative that you initialize EVERY property in your entity classes with either "),e.j41(89,"i"),e.EFF(90,"null"),e.k0s(),e.EFF(91,", "),e.j41(92,"i"),e.EFF(93,"undefined"),e.k0s(),e.EFF(94,", or with actual values. Lists and Arrays should be empty or null."),e.k0s(),e.j41(95,"p",4),e.EFF(96,"Never initialize a property like this. It will cause any entity mapping to fail:"),e.k0s(),e.j41(97,"pre"),e.nrm(98,"code",3),e.k0s(),e.j41(99,"p",2),e.EFF(100,"The reason is, that this property is impossible to see with reflection due to it being un-initialized. If you need your properties to be uninitialized just set them to 'undefined'"),e.k0s(),e.j41(101,"pre"),e.nrm(102,"code",3),e.k0s(),e.j41(103,"h2"),e.EFF(104,"The EntityDataService"),e.k0s(),e.j41(105,"p",2),e.EFF(106,"The "),e.j41(107,"i"),e.EFF(108,"EntityMapper"),e.k0s(),e.EFF(109," is also used together with the "),e.j41(110,"i"),e.EFF(111,"EntityDataService"),e.k0s(),e.EFF(112,". This injectable service includes methods for fetching data over REST. It will call the "),e.j41(113,"i"),e.EFF(114,"EntityMapper"),e.k0s(),e.EFF(115," on the return of all data and convert the JSON data over to objects using the mapper. This is the a simplified way to do it, but you can of course use the mapper completely standalone."),e.k0s(),e.j41(116,"p",2),e.EFF(117,"To inject it, simply include it in your constructor per:"),e.k0s(),e.j41(118,"pre"),e.nrm(119,"code",3),e.k0s(),e.j41(120,"h2"),e.EFF(121,"Using the EntityMapper By Itself"),e.k0s(),e.j41(122,"p",2),e.EFF(123,"The base usage is like the example below. You always start the mapping from the root object if your object is a tree of data. Any subsequent entities will be automatically mapped from the root out to the end of every tree."),e.k0s(),e.j41(124,"pre"),e.nrm(125,"code",3),e.k0s(),e.j41(126,"p",2),e.EFF(127,"Let's say our jsonObj is an array of "),e.j41(128,"i"),e.EFF(129,"Currency"),e.k0s(),e.EFF(130," data that matches the example class at the top:"),e.k0s(),e.j41(131,"pre"),e.nrm(132,"code",3),e.k0s(),e.j41(133,"p",2),e.EFF(134,"We know we want any array of "),e.j41(135,"i"),e.EFF(136,"Currency"),e.k0s(),e.EFF(137," entity objects as the result. To map them all we do as follows:"),e.k0s(),e.j41(138,"pre"),e.nrm(139,"code",3),e.k0s(),e.j41(140,"h2"),e.EFF(141,"Using BaseEntity with Code Generators & Automatically Generated Classes"),e.k0s(),e.j41(142,"p",2),e.EFF(143,"A lot of time you will have your base entities generated by some code generation framework. This causes headaches for changing entities as you cannot modify the class itself without having any changes being overwritten the next tiem the generation is done. To get around this, one way to tackle it is to add a post-processing task to your Maven build or whatever you use to build your code."),e.k0s(),e.j41(144,"p",2),e.EFF(145,"Here is an example from an existing project that goes through entities and adds annotations to the generated base classes (in this case, using the Open API generator)."),e.k0s(),e.j41(146,"pre"),e.nrm(147,"code",5),e.k0s()()()),2&n&&(e.R7$(9),e.Y8G("highlight","let classObj:TargetClass = (TargetClass) json"),e.R7$(26),e.Y8G("highlight","export class YourClass implements BaseEntity<YourClass> {"),e.R7$(8),e.Y8G("highlight","EntityMapper.mapEntityTreeFrom(jsonObjStructure, targetObject, EntityClassToMapTo, this.entityDataService);"),e.R7$(16),e.Y8G("highlight",s.easyRestCode),e.R7$(20),e.Y8G("highlight",s.baseEntityCode),e.R7$(19),e.Y8G("highlight",s.badInitCode),e.R7$(4),e.Y8G("highlight",s.goodInitCode),e.R7$(17),e.Y8G("highlight","constructor(private entityMapper: EntityMapper) {"),e.R7$(6),e.Y8G("highlight","EntityMapper.mapEntityFrom(jsonObj, targetObj, EntityClassToMapTo, entityDataService);"),e.R7$(7),e.Y8G("highlight",s.currencyCode),e.R7$(7),e.Y8G("highlight",s.currencyMappingCode),e.R7$(8),e.Y8G("highlight",s.mavenExampleCode))},dependencies:[r.f4],encapsulation:2,changeDetection:0})}}return t})()},{path:"annotations",component:(()=>{class t extends o.PJ{constructor(){super(),this.exampleCode='import {UnixDate} from "@six-group/base-angular-framework/core/DecoratorsModule";\n\nexport class CalendarDay extends BaseEntity<CalendarDay> {\n\n @UnixDate()\n date: Date = null;\n\n getClassName(): string {\n return "CalendarDay";\n }\n}',this.tableData=[{name:"ISODate",usage:"@ISODate() property: Date",attributes:"None",description:"Converts an ISO Date into a Date object",other:"",example:"@ISODate() isoDate: Date = undefined;"},{name:"UnixDate",usage:"@UnixDate() property:Date",attributes:"None",description:'Converts a UNIX "number" into a Date object',other:"",example:"@UnixDate() uxDate: Date = undefined;"},{name:"GeneratedId",usage:"@GeneratedId() property: String",attributes:"None",description:"Creates a unique generated ID for every creation of a class using this annotation",other:"The id uses numbers that ever increase starting at 0",example:"@GeneratedId() _id: String = undefined;"},{name:"FormattedDate",usage:"@FormattedDate(dateFormat)",attributes:"Date Format",description:"Takes a string date representing the target format and converts it to a Date",other:"",example:"@FormattedDate('YYYY-MM-DD') ymdDate: Date = undefined;"},{name:"ListDecorator",usage:'@List("TargetClass") property:T[]',attributes:"Target Class",description:"Assumes the property is a list of classes of the type given in the argument (matches getClassName() on BaseEntity)",other:"",example:'@List("MyClass") myClasses: MyClass[] = undefined;'},{name:"ObjectMapping",usage:'@ObjectMapping("TargetClass") property:Clazz',attributes:"Target Class",description:"Assumes the property is a single object of the type given in the argument (matches getClassName() on BaseEntity)",other:"",example:'@ObjectMapping("OtherClass") otherObj: OtherClass = undefined;'},{name:"StandardList",usage:"@StandardList() property:baseType[]\t",attributes:"None",description:"Assumes the property is a list of a standard type, such as string, integer, etc",other:"",example:"@StandardList() listOfStrings: String[] = undefined;"},{name:"ConvertToInt",usage:"@ConvertToInt() property:number\t",attributes:"None",description:"Converts the target to an integer (JS number)",other:"",example:"@ConvertToInt() intValueOfStr: value = undefined;"},{name:"ConvertToFloat",usage:"@ConvertToFloat() property:number",attributes:"None",description:"Converts the target to a float (JS number with decimals)",other:"",example:"@ConvertToFloat() floatValueOfStr: value = undefined;"}]}getEventGrid(a){}hookObservables(){}ngOnInit(){super.ngOnInit()}ngAfterViewInit(){super.ngAfterViewInit()}ngOnDestroy(){super.ngOnDestroy()}static{this.\u0275fac=function(n){return new(n||t)}}static{this.\u0275cmp=e.VBU({type:t,selectors:[["AnnotationsView"]],features:[e.Jv_([]),e.Vt3],decls:33,vars:2,consts:[["xmlns","http://www.w3.org/1999/html",1,"documentParent"],[1,"document"],[1,"description"],["language","ts",3,"highlight"],[1,"doc-table"],[4,"ngFor","ngForOf"],["id","api.menu.props.model",1,"doc-option-name"],[1,"doc-option-link"],[1,"pi","pi-link"],[1,"doc-option-type"],["id","api.menu.props.attributes",1,"doc-option-light","doc-option-default"],["id","api.menu.props.description",1,"doc-option-description"],["id","api.menu.props.other",1,"doc-option-description"],["id","api.menu.props.example",1,"doc-option-description"]],template:function(n,s){1&n&&(e.j41(0,"div",0)(1,"div",1)(2,"h1"),e.EFF(3,"Annotations and Decorators"),e.k0s(),e.j41(4,"div",2),e.EFF(5,"Annotations on properties in your entities defines how the raw json properties are converted into real objects. For the most general usecases of mapping data (for example strings into Date objects), many annotations are provided by the framework."),e.k0s(),e.j41(6,"div",2),e.EFF(7,"Example of annotation usage where a string UNIX date would be converted into a JS Date Object"),e.k0s(),e.j41(8,"pre"),e.nrm(9,"code",3),e.k0s(),e.nrm(10,"p"),e.j41(11,"div",2),e.EFF(12,"Here are the annotations that are in the framework already. If you need to convert things that are not covered here, please go on to the next section in the menu"),e.k0s(),e.nrm(13,"p"),e.j41(14,"h2"),e.EFF(15,"Provided Annotations"),e.k0s(),e.j41(16,"table",4)(17,"thead")(18,"tr")(19,"th"),e.EFF(20," name"),e.k0s(),e.j41(21,"th"),e.EFF(22," usage"),e.k0s(),e.j41(23,"th"),e.EFF(24," attributes"),e.k0s(),e.j41(25,"th"),e.EFF(26," description"),e.k0s(),e.j41(27,"th"),e.EFF(28," other info"),e.k0s(),e.j41(29,"th"),e.EFF(30," example code"),e.k0s()()(),e.j41(31,"tbody"),e.DNE(32,d,22,6,"tr",5),e.k0s()()()()),2&n&&(e.R7$(9),e.Y8G("highlight",s.exampleCode),e.R7$(23),e.Y8G("ngForOf",s.tableData))},dependencies:[p.Sq,r.f4],encapsulation:2,changeDetection:0})}}return t})()},{path:"customAnnotations",component:(()=>{class t extends o.PJ{constructor(){super(),this.constuctorCode='import {DecoratorRegistry} from "@six-group/base-angular-framework/core";\n\n...\n\nconstructor(private decoratorRegistry: DecoratorRegistry) {',this.sampleUsageCode='import {BaseEntity} from "@six-group/base-angular-framework/core";\nimport {Test} from "./TestDecorator";\n\nexport class TestClass implements BaseEntity<TestClass> {\n\n @Test()\n prop: string = null;\n\n getClassName(): string {\n return "TestClass";\n }\n\n postProcess() {\n }\n}',this.sampleRegistrationCode='import {getTest, Test} from "./test/data/decorators/TestDecorator";\n\n...\n\nngOnInit() {\n try {\n this.decoratorRegistry.register(Test, getTest, (prop, val, params) => {\n if (params) {\n return params;\n }\n return "It worked!";\n });\n } catch (err) {\n console.error(err);\n }\n}',this.sampleAnnotationCode='import "reflect-metadata";\n\nconst decoratorMetadataKey = Symbol("Test");\n\nexport function Test(formatString: string = null) {\n return Reflect.metadata(decoratorMetadataKey, formatString);\n}\n\nexport function getTest(target: any, propertyKey: string) {\n return Reflect.getMetadata(decoratorMetadataKey, target, propertyKey);\n}'}getEventGrid(a){}hookObservables(){}ngOnInit(){super.ngOnInit()}ngAfterViewInit(){super.ngAfterViewInit()}ngOnDestroy(){super.ngOnDestroy()}static{this.\u0275fac=function(n){return new(n||t)}}static{this.\u0275cmp=e.VBU({type:t,selectors:[["CustomAnnotationsView"]],features:[e.Jv_([]),e.Vt3],decls:59,vars:4,consts:[["xmlns","http://www.w3.org/1999/html",1,"documentParent"],[1,"document"],[1,"description"],["language","ts",3,"highlight"],["type","1"]],template:function(n,s){1&n&&(e.j41(0,"div",0)(1,"div",1)(2,"h1"),e.EFF(3,"Custom Annotations and the DecoratorRegistry"),e.k0s(),e.j41(4,"p",2),e.EFF(5,"When the provided annotations are not enough, creating your own is the way to go. An annotation in Javscript is essentially a "),e.j41(6,"i"),e.EFF(7,"Decorator"),e.k0s(),e.EFF(8," and is created by quite specific code. This section will go over creating your own and registering them with the "),e.j41(9,"i"),e.EFF(10,"EntityMapper"),e.k0s(),e.EFF(11,"."),e.k0s(),e.j41(12,"h2"),e.EFF(13,"Sample Annotation (Decorator) named "),e.j41(14,"i"),e.EFF(15,"@Test"),e.k0s()(),e.j41(16,"pre"),e.nrm(17,"code",3),e.k0s(),e.j41(18,"h2"),e.EFF(19,"DecoratorRegistry"),e.k0s(),e.j41(20,"p",2),e.EFF(21,"All annotation registration (so that the "),e.j41(22,"i"),e.EFF(23,"EntityMapper"),e.k0s(),e.EFF(24," is aware of your custom annotation) is done via the "),e.j41(25,"i"),e.EFF(26,"DecoratorRegistry"),e.k0s(),e.EFF(27," service. First, inject the "),e.j41(28,"i"),e.EFF(29,"DecoratorRegistry"),e.k0s(),e.EFF(30," in your constructor as as follows: "),e.k0s(),e.j41(31,"pre"),e.nrm(32,"code",3),e.k0s(),e.j41(33,"p",2),e.EFF(34,"We then register the annotation to it via:"),e.k0s(),e.j41(35,"pre"),e.nrm(36,"code",3),e.k0s(),e.j41(37,"p",2),e.EFF(38,"Once it's registered, we can add it to our entity class where we wish to use it:"),e.k0s(),e.j41(39,"pre"),e.nrm(40,"code",3),e.k0s(),e.j41(41,"p",2),e.EFF(42,"In this test case, the annotation would per the above code do the following:"),e.k0s(),e.j41(43,"ol",4)(44,"li")(45,"p",2),e.EFF(46,"If there is a parameter passed along with the "),e.j41(47,"i"),e.EFF(48,"@Test()"),e.k0s(),e.EFF(49," annotation, such as "),e.j41(50,"i"),e.EFF(51,"@Test('Hi there!')"),e.k0s(),e.EFF(52,', then the value of "prop" will be "Hi there!"'),e.k0s()(),e.j41(53,"li")(54,"p",2),e.EFF(55,"If there is no parameter passed along with the "),e.j41(56,"i"),e.EFF(57,"@Test()"),e.k0s(),e.EFF(58,' annotation, then the value is "It worked!"'),e.k0s()()()()()),2&n&&(e.R7$(17),e.Y8G("highlight",s.sampleAnnotationCode),e.R7$(15),e.Y8G("highlight",s.constuctorCode),e.R7$(4),e.Y8G("highlight",s.sampleRegistrationCode),e.R7$(4),e.Y8G("highlight",s.sampleUsageCode))},dependencies:[r.f4],encapsulation:2,changeDetection:0})}}return t})()},{path:"reverseMapping",component:(()=>{class t extends o.PJ{constructor(){super(),this.backToJsonCode="let json = this.entityUtilities.prepareForSaving<Clazz>(jsObject);\n\nthis.someRestService.save(json).subscribe((response: any) => {\n...\n"}getEventGrid(a){}hookObservables(){}ngOnInit(){super.ngOnInit()}ngAfterViewInit(){super.ngAfterViewInit()}ngOnDestroy(){super.ngOnDestroy()}static{this.\u0275fac=function(n){return new(n||t)}}static{this.\u0275cmp=e.VBU({type:t,selectors:[["ReverseMappingView"]],features:[e.Jv_([]),e.Vt3],decls:43,vars:2,consts:[["xmlns","http://www.w3.org/1999/html",1,"documentParent"],[1,"document"],[1,"description"],["language","ts",3,"highlight"],["href","https://gitlab.six-group.net/six/angbase/root/base/-/blob/main/src/app/components/core/src/services/EntityUtilities.ts","target","_blank"]],template:function(n,s){1&n&&(e.j41(0,"div",0)(1,"div",1)(2,"h1"),e.EFF(3,"Converting "),e.j41(4,"i"),e.EFF(5,"BaseEntity"),e.k0s(),e.EFF(6," implementations back to JSON"),e.k0s(),e.j41(7,"p",2),e.EFF(8,"Mapping from JSON to entities is great. But many times we need to send object graphs back to the server as JSON, and this is again where a lot of headaches can happen as you may have back-references which cause infinite loops etc when trying to use the basic "),e.j41(9,"i"),e.EFF(10,"JSON.stringify(object)"),e.k0s(),e.EFF(11,"."),e.k0s(),e.j41(12,"p",2),e.EFF(13,'We may also have added "temporary properties" that actually don\'t belong to the object via code, such as '),e.j41(14,"i"),e.EFF(15,'obj["thisIsNew"] = "blah"'),e.k0s(),e.EFF(16,", and as they technically didn't exist on the object from the beginning, they should also not be sent back."),e.k0s(),e.j41(17,"p",2),e.EFF(18,"To ensure all of this works as intended, the "),e.j41(19,"i"),e.EFF(20,"EntityMapping"),e.k0s(),e.EFF(21," framework comes with a utility that lets you convert your object structure back to JSON."),e.k0s(),e.j41(22,"p",2),e.EFF(23,"First we inject the "),e.j41(24,"i"),e.EFF(25,"EntityUtilities"),e.k0s(),e.EFF(26," service into our constructor."),e.k0s(),e.j41(27,"pre"),e.nrm(28,"code",3),e.k0s(),e.j41(29,"p",2),e.EFF(30,"Now we can tell "),e.j41(31,"i"),e.EFF(32,"EntityUtilities"),e.k0s(),e.EFF(33," that we need to convert our object (that implements "),e.j41(34,"i"),e.EFF(35,"BaseEntity"),e.k0s(),e.EFF(36,") back to JSON"),e.k0s(),e.j41(37,"pre"),e.nrm(38,"code",3),e.k0s(),e.j41(39,"p",2),e.EFF(40,"This is a very simple example. The converter takes many optional parameters as well that lets you override properties, do custom conversion before or after. For more details, "),e.j41(41,"a",4),e.EFF(42,"please read the API documentation for the class"),e.k0s()()()()),2&n&&(e.R7$(28),e.Y8G("highlight","constructor(private entityUtilities: EntityUtilities) {"),e.R7$(10),e.Y8G("highlight",s.backToJsonCode))},dependencies:[r.f4],encapsulation:2,changeDetection:0})}}return t})()}]);let m=(()=>{class t extends o.of{constructor(a){super(),this.errorHelper=a}destroy(){}handleInitializionError(a){this.errorHelper.displayError(a)}hookObservables(){}static{this.\u0275fac=function(n){return new(n||t)(e.KVO(o.V_))}}static{this.\u0275prov=e.jDH({token:t,factory:t.\u0275fac})}}return t})();var F=i(928),y=i(6160);let E=(()=>{class t{static{this.\u0275fac=function(n){return new(n||t)}}static{this.\u0275mod=e.$C({type:t})}static{this.\u0275inj=e.G2t({providers:[m],imports:[p.MD,g,F.G,y.$V]})}}return t})()}}]);