1# getTarget API: Obtaining Original Objects 2 3To obtain the original object before adding a proxy in the state management, you can use the [getTarget](../reference/apis-arkui/js-apis-StateManagement.md#gettarget12) API. 4 5Before reading this topic, you are advised to read [\@Observed](./arkts-observed-and-objectlink.md) and [\@ObservedV2](./arkts-new-observedV2-and-trace.md). 6 7>**NOTE** 8> 9>The **getTarget** API in UIUtils is supported since API version 12. 10 11## Overview 12 13The state management framework adds proxies to original objects of the Class, Date, Map, Set, and Array types to observe attribute changes and API invoking. Proxies will change the variable types. In scenarios such as type determination and Node-API invoking, unexpected results may be generated because the variable type is not the type of the original object. 14 15- Import the UIUtils to use the **getTarget** API. 16 17 ```ts 18 import { UIUtils } from '@kit.ArkUI'; 19 ``` 20 21- In state management V1, a proxy is added to the class objects decorated by @Observed and the Class, Date, Map, Set, and Array decorated by @State or other state variable decorators to observe the changes of top-level attributes or changes invoked by APIs. 22- In state management V2, a proxy is added to Date, Map, Set, and Array decorated by \@Trace, \@Local or other state variable decorators to observe changes invoked by APIs. 23 24Use **getTarget** to obtain the original objects of these proxy objects. 25 26## Constraints 27 28- Only the parameters of the object type can be passed by **getTarget**. 29 30 ```ts 31 import { UIUtils } from '@kit.ArkUI'; 32 let res = UIUtils.getTarget(2); // Incorrect usage. The input parameter is of the non-object type. 33 @Observed 34 class Info { 35 name: string = "Tom"; 36 } 37 let info: Info = new Info(); 38 let rawInfo: Info = UIUtils.getTarget (info); // Correct usage. 39 ``` 40 41- Changes to the content in the original object obtained by **getTarget** cannot be observed nor trigger UI re-renders. 42 43 ```ts 44 import { UIUtils } from '@kit.ArkUI'; 45 @Observed 46 class Info { 47 name: string = "Tom"; 48 } 49 @Entry 50 @Component 51 struct Index { 52 @State info: Info = new Info(); 53 54 build() { 55 Column() { 56 Text(`info.name: ${this.info.name}`) 57 Button(`Change the attributes of the proxy object`) 58 .onClick(() => { 59 this.info.name = "Alice"; // Text component can be re-rendered. 60 }) 61 Button (`Change the attributes of the original object`) 62 .onClick(() => { 63 let rawInfo: Info = UIUtils.getTarget(this.info); 64 The rawInfo.name = "Bob"; // Text component cannot be re-rendered. 65 }) 66 } 67 } 68 } 69 ``` 70 71## Use Scenarios 72 73### Obtains the original object before adding a proxy in the state management V1. 74 75State management V1 adds proxies to objects in the following scenarios: 76 771. \@Observed decorated class instance. When this class instance is created, a proxy is added to the instance. However, objects that are not created by using the **new** operator are not proxied. 78 79```ts 80@Observed 81class ObservedClass { 82 name: string = "Tom"; 83} 84class NonObservedClass { 85 name: string = "Tom"; 86} 87let observedClass: ObservedClass = new ObservedClass(); // Proxied. 88let nonObservedClass: NonObservedClass = new NonObservedClass(); // Not proxied. 89``` 90 912. Complex object decorated by the state variable decorator. When state variables decorators such as \@State or \@Prop are used to decorate Class, Map, Set, Date, and Array, proxies are added. If the object is already a proxy object, the proxy will not be created again. 92 93```ts 94@Observed 95class ObservedClass { 96 name: string = "Tom"; 97} 98class NonObservedClass { 99 name: string = "Tom"; 100} 101let observedClass: ObservedClass = new ObservedClass(); // Proxied. 102let nonObservedClass: NonObservedClass = new NonObservedClass(); // Not proxied. 103@Entry 104@Component 105struct Index { 106 @State observedObject: ObservedClass = observedClass; // Proxy will not be created repeatedly for proxied data. 107 @State nonObservedObject: NonObservedClass = nonObservedClass; // A proxy is created. 108 @State numberList: number[] = [1, 2, 3]; // A proxy is created for the Array type. 109 @State sampleMap: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]]); // A proxy is created for the Map type. 110 @State sampleSet: Set<number> = new Set([0, 1, 2, 3, 4]); // A proxy is created for the Set type. 111 @State sampleDate: Date = new Date(); // A proxy is created for the Date type. 112 113 build() { 114 Column() { 115 Text(`this.observedObject === observedClass: ${this.observedObject === observedClass}`) // true 116 Text(`this.nonObservedObject === nonObservedClass: ${this.nonObservedObject === nonObservedClass}`) // false 117 } 118 } 119} 120``` 121 122Use **UIUtils.getTarget** to obtain the original objects before proxies are added. 123 124```ts 125import { UIUtils } from '@kit.ArkUI'; 126@Observed 127class ObservedClass { 128 name: string = "Tom"; 129} 130class NonObservedClass { 131 name: string = "Tom"; 132} 133let observedClass: ObservedClass = new ObservedClass(); // Proxied. 134let nonObservedClass: NonObservedClass = new NonObservedClass(); // Not proxied. 135let globalNumberList: number[] = [1, 2, 3]; // Not proxied. 136let globalSampleMap: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]]); // Not proxied. 137let globalSampleSet: Set<number> = new Set([0, 1, 2, 3, 4]); // Not proxied. 138let globalSampleDate:Date = new Date (); // Not proxied. 139@Entry 140@Component 141struct Index { 142 @State observedObject: ObservedClass = observedClass; // Proxy will not be created repeatedly for proxied data. 143 @State nonObservedObject: NonObservedClass = nonObservedClass; // A proxy is created. 144 @State numberList: number[] = globalNumberList; // A proxy is created for the Array type. 145 @State sampleMap: Map<number, string> = globalSampleMap; // A proxy is created for the Map type. 146 @State sampleSet: Set<number> = globalSampleSet; // A proxy is created for the Set type. 147 @State sampleDate: Date = globalSampleDate; // A proxy is created for the Date type. 148 149 build() { 150 Column() { 151 Text(`this.observedObject === observedClass: ${this.observedObject === 152 observedClass}`) // true 153 Text(`UIUtils.getTarget(this.nonObservedObject) === nonObservedClass: ${UIUtils.getTarget(this.nonObservedObject) === 154 nonObservedClass}`) // true 155 Text(`UIUtils.getTarget(this.numberList) === globalNumberList: ${UIUtils.getTarget(this.numberList) === 156 globalNumberList}`) // true 157 Text(`UIUtils.getTarget(this.sampleMap) === globalSampleMap: ${UIUtils.getTarget(this.sampleMap) === 158 globalSampleMap}`) // true 159 Text(`UIUtils.getTarget(this.sampleSet) === globalSampleSet: ${UIUtils.getTarget(this.sampleSet) === 160 globalSampleSet}`) // true 161 Text(`UIUtils.getTarget(this.sampleDate) === globalSampleDate: ${UIUtils.getTarget(this.sampleDate) === 162 globalSampleDate}`) // true 163 } 164 } 165} 166``` 167 168### Obtains the original object before adding a proxy in the state management V2. 169 170A proxy is added to the Map, Set, Date, and Array decorated by \@Trace, \@Local, or other state variable decorators in state management V2. Different from state management V1, the class object instances are not proxied in state management V2. 171 172```ts 173@ObservedV2 174class ObservedClass { 175 @Trace name: string = "Tom"; 176} 177let globalObservedObject: ObservedClass = new ObservedClass(); // Not proxied. 178let globalNumberList: number[] = [1, 2, 3]; // Not proxied. 179let globalSampleMap: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]]); // Not proxied. 180let globalSampleSet: Set<number> = new Set([0, 1, 2, 3, 4]); // Not proxied. 181let globalSampleDate:Date = new Date (); // Not proxied. 182@Entry 183@ComponentV2 184struct Index { 185 @Local observedObject: ObservedClass = globalObservedObject; // Objects in V2 are not proxied. 186 @Local numberList: number[] = globalNumberList; // A proxy is created for the Array type. 187 @Local sampleMap: Map<number, string> = globalSampleMap; // A proxy is created for the Map type. 188 @Local sampleSet: Set<number> = globalSampleSet; // A proxy is created for the Set type. 189 @Local sampleDate: Date = globalSampleDate; // A proxy is created for the Date type. 190 191 build() { 192 Column() { 193 Text(`this.observedObject === globalObservedObject ${this.observedObject === globalObservedObject}`) // true 194 Text(`this.numberList === globalNumberList ${this.numberList === globalNumberList}`) // false 195 } 196 } 197} 198``` 199 200Use **UIUtils.getTarget** to obtain the original objects before proxies are added. 201 202```ts 203import { UIUtils } from '@kit.ArkUI'; 204@ObservedV2 205class ObservedClass { 206 @Trace name: string = "Tom"; 207} 208let globalObservedObject: ObservedClass = new ObservedClass(); // Not proxied. 209let globalNumberList: number[] = [1, 2, 3]; // Not proxied. 210let globalSampleMap: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]]); // Not proxied. 211let globalSampleSet: Set<number> = new Set([0, 1, 2, 3, 4]); // Not proxied. 212let globalSampleDate:Date = new Date (); // Not proxied. 213@Entry 214@ComponentV2 215struct Index { 216 @Local observedObject: ObservedClass = globalObservedObject; // Objects in V2 are not proxied. 217 @Local numberList: number[] = globalNumberList; // A proxy is created for the Array type. 218 @Local sampleMap: Map<number, string> = globalSampleMap; // A proxy is created for the Map type. 219 @Local sampleSet: Set<number> = globalSampleSet; // A proxy is created for the Set type. 220 @Local sampleDate: Date = globalSampleDate; // A proxy is created for the Date type. 221 222 build() { 223 Column() { 224 Text(`this.observedObject === globalObservedObject ${this.observedObject === 225 globalObservedObject}`) // true 226 Text(`UIUtils.getTarget(this.numberList) === globalNumberList: ${UIUtils.getTarget(this.numberList) === 227 globalNumberList}`) // true 228 Text(`UIUtils.getTarget(this.sampleMap) === globalSampleMAP: ${UIUtils.getTarget(this.sampleMap) === 229 globalSampleMap}`) // true 230 Text(`UIUtils.getTarget(this.sampleSet) === globalSampleSet: ${UIUtils.getTarget(this.sampleSet) === 231 globalSampleSet}`) // true 232 Text(`UIUtils.getTarget(this.sampleDate) === globalSampleDate: ${UIUtils.getTarget(this.sampleDate) === 233 globalSampleDate}`) // true 234 } 235 } 236} 237``` 238 239Decorators in state management V2 generate the **getter** and **setter** methods for the decorated variables and add prefix **\_\_ob\_** in the original variable names. To ensure performance, the **getTarget** API does not process the prefix generated by the decorators in V2. Therefore, when the \@ObservedV2 decorated class object instance is passed in through **getTarget** API, the returned object is still the object itself and the attribute name decorated by \@Trace still has the prefix **\_\_ob\_**. 240 241Some Node-APIs fail to process object attributes as expected due to this prefix.<br>Example:<br> 242 243```ts 244// Class decorated by @ObservedV2. 245@ObservedV2 246class Info { 247 @Trace name: string = "Tom"; 248 @Trace age: number = 24; 249} 250let info: Info = new Info(); // info instance passed in through Node-APIs. 251``` 252 253Affected Node-APIs are as below. 254| Name | Result | 255| ----------------------- | ---------------------------------------------- | 256| napi_get_property_names | Returns value that is **\_\_ob\_name** or **\_\_ob\_age**. | 257| napi_set_property | Changes values successfully using **name** or **\_\_ob\_name**. | 258| napi_get_property | Obtains values using **name** or **\_\_ob\_name**. | 259| napi_has_property | Returns **true** using **name** or **\_\_ob\_name**. | 260| napi_delete_property | Deletes an attribute successfully adding the prefix **\_\_ob\_**.| 261| napi_has_own_property | Returns **true** using **name** or **\_\_ob\_name**. | 262| napi_set_named_property | Changes values successfully using **name** or **\_\_ob\_name**. | 263| napi_get_named_property | Obtains values using **name** or **\_\_ob\_name**. | 264| napi_has_named_property | Returns **true** using **name** or **\_\_ob\_name**. | 265