Merge remote-tracking branch 'origin/tizen_3.0' into tizen_4.0
[platform/core/api/webapi-plugins.git] / src / datacontrol / datacontrol_api.js
index c92902d..94bf83b 100755 (executable)
  *    limitations under the License.
  */
 
-tizen.debug = extension;
-
-var JSON_ = xwalk.JSON;
 var validator_ = xwalk.utils.validator;
+var converter_ = xwalk.utils.converter;
 var types_ = validator_.Types;
+var type_ = xwalk.utils.type;
+var native_ = new xwalk.utils.NativeManager(extension);
 
-var callbackId = 0;
-var callbacks = {};
+var DATA_CONTROL_MANAGER_LISTENER_ID = 'DataControlManagerChangeCallback';
 
-extension.setMessageListener(function(json) {
-    var result = JSON_.parse(json);
-    var callback = callbacks[result['callbackId']];
-    setTimeout(function() {
-        callback(result);
-        delete callbacks[result['callbackId']];
-    }, 0);
-});
+var DataType = {
+    MAP: 'MAP',
+    SQL: 'SQL'
+};
 
-function nextCallbackId() {
-    return callbackId++;
-}
+var DataControlListenersManager = (function() {
+    function changeEvent(event) {
+        var successCallback;
 
-function callNative(cmd, args) {
-    var json = { cmd: cmd, args: args };
-    var argjson = JSON_.stringify(json);
-    var resultString = extension.internal.sendSyncMessage(argjson);
-    var result = JSON_.parse(resultString);
+        if (DataType.SQL === event.type.substr(0, 3)) {
+            if (type_.isEmptyObject(this._SQLDataControlCbMap)) {
+                return;
+            }
+            for (var listenerId in this._SQLDataControlCbMap) {
+                if (this._SQLDataControlCbMap.hasOwnProperty(listenerId)) {
+                    if (
+                        this._SQLDataControlCbMap[listenerId].providerId ===
+                            event.providerId &&
+                        this._SQLDataControlCbMap[listenerId].dataId === event.dataId
+                    ) {
+                        successCallback = this._SQLDataControlCbMap[listenerId]
+                            .changeCallback;
+                        if (type_.isFunction(successCallback)) {
+                            successCallback(event.type, {
+                                columns: event.columns,
+                                values: event.values
+                            });
+                        }
+                    }
+                }
+            }
+        } else {
+            if (type_.isEmptyObject(this._MAPDataControlCbMap)) {
+                return;
+            }
+            for (var listenerId in this._MAPDataControlCbMap) {
+                if (this._MAPDataControlCbMap.hasOwnProperty(listenerId)) {
+                    if (
+                        this._MAPDataControlCbMap[listenerId].providerId ===
+                            event.providerId &&
+                        this._MAPDataControlCbMap[listenerId].dataId === event.dataId
+                    ) {
+                        successCallback = this._MAPDataControlCbMap[listenerId]
+                            .changeCallback;
+                        if (type_.isFunction(successCallback)) {
+                            successCallback(event.type, {
+                                columns: event.columns,
+                                values: event.values
+                            });
+                        }
+                    }
+                }
+            }
+        }
+    }
 
-    if (typeof result !== 'object') {
-        throw new WebAPIException(WebAPIException.UNKNOWN_ERR);
+    function _DataControlListenerManager() {
+        this._SQLDataControlCbMap = {};
+        this._MAPDataControlCbMap = {};
+        this.lastListenerId = 0;
+        this.changeEvent = changeEvent.bind(this);
     }
 
-    if (result['status'] == 'success') {
-        if (result['result']) {
-            return result['result'];
+    _DataControlListenerManager.prototype.addChangeListener = function(
+        type,
+        providerId,
+        dataId,
+        changeCallback,
+        errorCallback
+    ) {
+        var _realWatchId = 0;
+        if (DataType.SQL === type) {
+            for (var i in this._SQLDataControlCbMap) {
+                if (
+                    this._SQLDataControlCbMap.hasOwnProperty(i) &&
+                    this._SQLDataControlCbMap[i].providerId === providerId &&
+                    this._SQLDataControlCbMap[i].dataId === dataId
+                ) {
+                    _realWatchId = this._SQLDataControlCbMap[i].realWatchId;
+                }
+            }
+        } else {
+            for (var i in this._MAPDataControlCbMap) {
+                if (
+                    this._MAPDataControlCbMap.hasOwnProperty(i) &&
+                    this._MAPDataControlCbMap[i].providerId === providerId &&
+                    this._MAPDataControlCbMap[i].dataId === dataId
+                ) {
+                    _realWatchId = this._MAPDataControlCbMap[i].realWatchId;
+                }
+            }
+        }
+
+        if (!_realWatchId) {
+            var callback = function(result) {
+                if (native_.isFailure(result)) {
+                    native_.callIfPossible(errorCallback, native_.getErrorObject(result));
+                    return;
+                }
+            };
+            var result = native_.call(
+                'DataControlConsumerObject_addChangeListener',
+                {
+                    providerId: providerId,
+                    dataId: dataId,
+                    type: type
+                },
+                callback
+            );
+
+            if (native_.isFailure(result)) {
+                throw native_.getErrorObject(result);
+            } else {
+                result = native_.getResultObject(result);
+                _realWatchId = converter_.toLong(result.watchId, true);
+            }
+            if (
+                type_.isEmptyObject(this._SQLDataControlCbMap) &&
+                type_.isEmptyObject(this._MAPDataControlCbMap)
+            ) {
+                native_.addListener(DATA_CONTROL_MANAGER_LISTENER_ID, this.changeEvent);
+            }
         }
-        return true;
-    } else if (result['status'] == 'error') {
-        var err = result['error'];
-        if (err) {
-            throw new WebAPIException(err);
+
+        if (DataType.SQL === type) {
+            this._SQLDataControlCbMap[++this.lastListenerId] = {
+                providerId: providerId,
+                dataId: dataId,
+                changeCallback: changeCallback,
+                realWatchId: _realWatchId
+            };
+        } else {
+            this._MAPDataControlCbMap[++this.lastListenerId] = {
+                providerId: providerId,
+                dataId: dataId,
+                changeCallback: changeCallback,
+                realWatchId: _realWatchId
+            };
         }
-        return false;
-    }
-}
 
-function callNativeWithCallback(cmd, args, callback) {
-    if (callback) {
-        var id = nextCallbackId();
-        args['callbackId'] = id;
-        callbacks[id] = callback;
-    }
+        return this.lastListenerId;
+    };
 
-    return callNative(cmd, args);
-}
+    _DataControlListenerManager.prototype.removeChangeListener = function(
+        type,
+        providerId,
+        dataId,
+        listenerId
+    ) {
+        var _realWatchId = 0;
+        if (
+            DataType.SQL === type &&
+            !type_.isUndefined(this._SQLDataControlCbMap[listenerId])
+        ) {
+            _realWatchId = this._SQLDataControlCbMap[listenerId].realWatchId;
+            delete this._SQLDataControlCbMap[listenerId];
+            for (var i in this._SQLDataControlCbMap) {
+                if (
+                    this._SQLDataControlCbMap.hasOwnProperty(i) &&
+                    this._SQLDataControlCbMap[i].realWatchId === _realWatchId
+                ) {
+                    return;
+                }
+            }
+        } else if (
+            DataType.MAP === type &&
+            !type_.isUndefined(this._MAPDataControlCbMap[listenerId])
+        ) {
+            _realWatchId = this._MAPDataControlCbMap[listenerId].realWatchId;
+            delete this._MAPDataControlCbMap[listenerId];
+            for (var i in this._MAPDataControlCbMap) {
+                if (
+                    this._MAPDataControlCbMap.hasOwnProperty(i) &&
+                    this._MAPDataControlCbMap[i].realWatchId === _realWatchId
+                ) {
+                    return;
+                }
+            }
+        } else {
+            console.log('Type invalid or listener was not added');
+            return;
+        }
+
+        if (0 != _realWatchId) {
+            native_.call('DataControlConsumerObject_removeChangeListener', {
+                watchId: _realWatchId
+            });
+
+            if (
+                type_.isEmptyObject(this._SQLDataControlCbMap) &&
+                type_.isEmptyObject(this._MAPDataControlCbMap)
+            ) {
+                native_.removeListener(DATA_CONTROL_MANAGER_LISTENER_ID);
+            }
+        }
+    };
+
+    return _DataControlListenerManager;
+})();
+
+var listenersManager = new DataControlListenersManager();
 
 function SetReadOnlyProperty(obj, n, v) {
     Object.defineProperty(obj, n, { value: v, writable: false });
 }
 
-var DataType = {
-    MAP: 'MAP',
-    SQL: 'SQL'
-};
-
 function DataControlManager() {
     // constructor of DataControlManager
 }
@@ -90,19 +239,22 @@ var getDataControlConsumer = function(providerId, dataId, type) {
     var args = validator_.validateArgs(arguments, [
         { name: 'providerId', type: types_.STRING },
         { name: 'dataId', type: types_.STRING },
-        { name: 'type', type: types_.ENUM, values: ['MAP', 'SQL'] }
+        { name: 'type', type: types_.ENUM, values: [DataType.SQL, DataType.MAP] }
     ]);
 
     var returnObject = null;
-    if (type === 'SQL') {
+    if (DataType.SQL === type) {
         returnObject = new SQLDataControlConsumer();
-    } else if (type === 'MAP') {
+    } else if (DataType.MAP == type) {
         returnObject = new MappedDataControlConsumer();
     }
-    SetReadOnlyProperty(returnObject, 'type', args.type); // read only property
+
+    // read only property
+    SetReadOnlyProperty(returnObject, 'type', args.type);
     // read only property
     SetReadOnlyProperty(returnObject, 'providerId', args.providerId);
-    SetReadOnlyProperty(returnObject, 'dataId', args.dataId); // read only property
+    // read only property
+    SetReadOnlyProperty(returnObject, 'dataId', args.dataId);
 
     return returnObject;
 };
@@ -115,6 +267,49 @@ function DataControlConsumerObject() {
     // constructor of DataControlConsumerObject
 }
 
+DataControlConsumerObject.prototype.addChangeListener = function() {
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'dataChangeCallback',
+            type: types_.FUNCTION,
+            optional: false,
+            nullable: false
+        },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
+    ]);
+
+    var type = DataType.SQL;
+    if (this instanceof MappedDataControlConsumer) {
+        type = DataType.MAP;
+    }
+
+    return listenersManager.addChangeListener(
+        type,
+        this.providerId,
+        this.dataId,
+        args.dataChangeCallback,
+        args.errorCallback
+    );
+};
+
+DataControlConsumerObject.prototype.removeChangeListener = function() {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'watchId', type: types_.LONG }
+    ]);
+
+    var type = DataType.SQL;
+    if (this instanceof MappedDataControlConsumer) {
+        type = DataType.MAP;
+    }
+
+    listenersManager.removeChangeListener(
+        type,
+        this.providerId,
+        this.dataId,
+        args.watchId
+    );
+};
+
 function SQLDataControlConsumer() {
     // constructor of SQLDataControlConsumer
 }
@@ -122,7 +317,7 @@ function SQLDataControlConsumer() {
 SQLDataControlConsumer.prototype = new DataControlConsumerObject();
 SQLDataControlConsumer.prototype.constructor = SQLDataControlConsumer;
 
-SQLDataControlConsumer.prototype.insert = function(reqId, insertionData) {
+SQLDataControlConsumer.prototype.insert = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'insertionData', type: types_.DICTIONARY },
@@ -150,31 +345,30 @@ SQLDataControlConsumer.prototype.insert = function(reqId, insertionData) {
         reqId: args.reqId,
         insertionData: args.insertionData
     };
-    try {
-        var syncResult = callNativeWithCallback(
-            'SQLDataControlConsumer_insert',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    if (args.successCallback) {
-                        args.successCallback(result['requestId'], result['result']);
-                    }
-                }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
-                }
+
+    var syncResult = native_.call('SQLDataControlConsumer_insert', nativeParam, function(
+        result
+    ) {
+        if (result.status == 'success') {
+            if (args.successCallback) {
+                args.successCallback(result['requestId'], result['result']);
+            }
+        }
+        if (result.status == 'error') {
+            if (args.errorCallback) {
+                var err = result['result'];
+                var e = new WebAPIException(err.name, err.message);
+                args.errorCallback(result['requestId'], e);
             }
-        );
-    } catch (e) {
-        throw e;
+        }
+    });
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };
 
-SQLDataControlConsumer.prototype.update = function(reqId, updateData, where) {
+SQLDataControlConsumer.prototype.update = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'updateData', type: types_.DICTIONARY },
@@ -195,31 +389,30 @@ SQLDataControlConsumer.prototype.update = function(reqId, updateData, where) {
         where: args.where,
         updateData: args.updateData
     };
-    try {
-        var syncResult = callNativeWithCallback(
-            'SQLDataControlConsumer_update',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    if (args.successCallback) {
-                        args.successCallback(result['requestId']);
-                    }
-                }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
-                }
+
+    var syncResult = native_.call('SQLDataControlConsumer_update', nativeParam, function(
+        result
+    ) {
+        if (result.status == 'success') {
+            if (args.successCallback) {
+                args.successCallback(result['requestId']);
             }
-        );
-    } catch (e) {
-        throw e;
+        }
+        if (result.status == 'error') {
+            if (args.errorCallback) {
+                var err = result['result'];
+                var e = new WebAPIException(err.name, err.message);
+                args.errorCallback(result['requestId'], e);
+            }
+        }
+    });
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };
 
-SQLDataControlConsumer.prototype.remove = function(reqId, where) {
+SQLDataControlConsumer.prototype.remove = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'where', type: types_.STRING },
@@ -238,54 +431,38 @@ SQLDataControlConsumer.prototype.remove = function(reqId, where) {
         reqId: args.reqId,
         where: args.where
     };
-    try {
-        var syncResult = callNativeWithCallback(
-            'SQLDataControlConsumer_remove',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    if (args.successCallback) {
-                        args.successCallback(result['requestId']);
-                    }
-                }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
-                }
+
+    var syncResult = native_.call('SQLDataControlConsumer_remove', nativeParam, function(
+        result
+    ) {
+        if (result.status == 'success') {
+            if (args.successCallback) {
+                args.successCallback(result['requestId']);
             }
-        );
-    } catch (e) {
-        throw e;
+        }
+        if (result.status == 'error') {
+            if (args.errorCallback) {
+                var err = result['result'];
+                var e = new WebAPIException(err.name, err.message);
+                args.errorCallback(result['requestId'], e);
+            }
+        }
+    });
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };
 
-SQLDataControlConsumer.prototype.select = function(
-    reqId,
-    columns,
-    where,
-    successCallback
-) {
+SQLDataControlConsumer.prototype.select = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'columns', type: types_.ARRAY },
         { name: 'where', type: types_.STRING },
         { name: 'successCallback', type: types_.FUNCTION },
-        {
-            name: 'errorCallback',
-            type: types_.FUNCTION,
-            optional: true,
-            nullable: true
-        },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true },
         { name: 'page', type: types_.LONG, optional: true, nullable: true },
-        {
-            name: 'maxNumberPerPage',
-            type: types_.LONG,
-            optional: true,
-            nullable: true
-        },
+        { name: 'maxNumberPerPage', type: types_.LONG, optional: true, nullable: true },
         { name: 'order', type: types_.STRING, optional: true, nullable: true }
     ]);
 
@@ -306,26 +483,23 @@ SQLDataControlConsumer.prototype.select = function(
         nativeParam['order'] = args.order;
     }
 
-    try {
-        var syncResult = callNativeWithCallback(
-            'SQLDataControlConsumer_select',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    args.successCallback(result['result'], result['requestId']);
-                }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
-                }
+    var syncResult = native_.call('SQLDataControlConsumer_select', nativeParam, function(
+        result
+    ) {
+        if (result.status == 'success') {
+            args.successCallback(result['result'], result['requestId']);
+        }
+        if (result.status == 'error') {
+            if (args.errorCallback) {
+                var err = result['result'];
+                var e = new WebAPIException(err.name, err.message);
+                args.errorCallback(result['requestId'], e);
             }
-        );
-        // if you need synchronous result from native function using 'syncResult'.
-    } catch (e) {
-        throw e;
+        }
+    });
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };
 
@@ -336,7 +510,7 @@ function MappedDataControlConsumer() {
 MappedDataControlConsumer.prototype = new DataControlConsumerObject();
 MappedDataControlConsumer.prototype.constructor = MappedDataControlConsumer;
 
-MappedDataControlConsumer.prototype.addValue = function(reqId, key, value) {
+MappedDataControlConsumer.prototype.addValue = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'key', type: types_.STRING },
@@ -347,12 +521,7 @@ MappedDataControlConsumer.prototype.addValue = function(reqId, key, value) {
             optional: true,
             nullable: true
         },
-        {
-            name: 'errorCallback',
-            type: types_.FUNCTION,
-            optional: true,
-            nullable: true
-        }
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
     ]);
 
     var nativeParam = {
@@ -362,36 +531,32 @@ MappedDataControlConsumer.prototype.addValue = function(reqId, key, value) {
         key: args.key,
         value: args.value
     };
-    try {
-        var syncResult = callNativeWithCallback(
-            'MappedDataControlConsumer_addValue',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    if (args.successCallback) {
-                        args.successCallback(result['requestId']);
-                    }
+
+    var syncResult = native_.call(
+        'MappedDataControlConsumer_addValue',
+        nativeParam,
+        function(result) {
+            if (result.status == 'success') {
+                if (args.successCallback) {
+                    args.successCallback(result['requestId']);
                 }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
+            }
+            if (result.status == 'error') {
+                if (args.errorCallback) {
+                    var err = result['result'];
+                    var e = new WebAPIException(err.name, err.message);
+                    args.errorCallback(result['requestId'], e);
                 }
             }
-        );
-    } catch (e) {
-        throw e;
+        }
+    );
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };
 
-MappedDataControlConsumer.prototype.removeValue = function(
-    reqId,
-    key,
-    value,
-    successCallback
-) {
+MappedDataControlConsumer.prototype.removeValue = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'key', type: types_.STRING },
@@ -407,29 +572,30 @@ MappedDataControlConsumer.prototype.removeValue = function(
         key: args.key,
         value: args.value
     };
-    try {
-        var syncResult = callNativeWithCallback(
-            'MappedDataControlConsumer_removeValue',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    args.successCallback(result['requestId']);
-                }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
+
+    var syncResult = native_.call(
+        'MappedDataControlConsumer_removeValue',
+        nativeParam,
+        function(result) {
+            if (result.status == 'success') {
+                args.successCallback(result['requestId']);
+            }
+            if (result.status == 'error') {
+                if (args.errorCallback) {
+                    var err = result['result'];
+                    var e = new WebAPIException(err.name, err.message);
+                    args.errorCallback(result['requestId'], e);
                 }
             }
-        );
-    } catch (e) {
-        throw e;
+        }
+    );
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };
 
-MappedDataControlConsumer.prototype.getValue = function(reqId, key, successCallback) {
+MappedDataControlConsumer.prototype.getValue = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'key', type: types_.STRING },
@@ -443,35 +609,30 @@ MappedDataControlConsumer.prototype.getValue = function(reqId, key, successCallb
         reqId: args.reqId,
         key: args.key
     };
-    try {
-        var syncResult = callNativeWithCallback(
-            'MappedDataControlConsumer_getValue',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    args.successCallback(result['result'], result['requestId']);
-                }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
+
+    var syncResult = native_.call(
+        'MappedDataControlConsumer_getValue',
+        nativeParam,
+        function(result) {
+            if (result.status == 'success') {
+                args.successCallback(result['result'], result['requestId']);
+            }
+            if (result.status == 'error') {
+                if (args.errorCallback) {
+                    var err = result['result'];
+                    var e = new WebAPIException(err.name, err.message);
+                    args.errorCallback(result['requestId'], e);
                 }
             }
-        );
-    } catch (e) {
-        throw e;
+        }
+    );
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };
 
-MappedDataControlConsumer.prototype.updateValue = function(
-    reqId,
-    key,
-    oldValue,
-    newValue,
-    successCallback
-) {
+MappedDataControlConsumer.prototype.updateValue = function() {
     var args = validator_.validateArgs(arguments, [
         { name: 'reqId', type: types_.LONG },
         { name: 'key', type: types_.STRING },
@@ -489,25 +650,26 @@ MappedDataControlConsumer.prototype.updateValue = function(
         oldValue: args.oldValue,
         newValue: args.newValue
     };
-    try {
-        var syncResult = callNativeWithCallback(
-            'MappedDataControlConsumer_updateValue',
-            nativeParam,
-            function(result) {
-                if (result.status == 'success') {
-                    args.successCallback(result['requestId']);
-                }
-                if (result.status == 'error') {
-                    if (args.errorCallback) {
-                        var err = result['result'];
-                        var e = new WebAPIException(err.name, err.message);
-                        args.errorCallback(result['requestId'], e);
-                    }
+
+    var syncResult = native_.call(
+        'MappedDataControlConsumer_updateValue',
+        nativeParam,
+        function(result) {
+            if (result.status == 'success') {
+                args.successCallback(result['requestId']);
+            }
+            if (result.status == 'error') {
+                if (args.errorCallback) {
+                    var err = result['result'];
+                    var e = new WebAPIException(err.name, err.message);
+                    args.errorCallback(result['requestId'], e);
                 }
             }
-        );
-    } catch (e) {
-        throw e;
+        }
+    );
+
+    if (native_.isFailure(syncResult)) {
+        throw native_.getErrorObject(syncResult);
     }
 };