Update db statement throwing jsonparse exception - Mobile, Intelligent Bot, and Mobile Analytics

Hi All I want to update the table row in mcs using custom query. for that I am using below shown method implementation:    service.put('---------/:name', function(req,res) {           var optionsList = {                uri: '/mobile/platform/database/sql?USERNAME=' + req.params.name,                headers: {                    'Content-Type': 'text/html',                    'Oracle-Mobile-SQL':'UPDATE "Mcs_Users" SET "PASSWORD" = "dsf" WHERE "USERNAME" = :USERNAME'                }            };                                 req.oracleMobile.rest.post(optionsList,             function(error, response, body) {              var message = error ? error.message : body;              res.status(response.statusCode).send(message);              res.end();            });    }); I am getting  bellow shown exception:{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1","status":400,"title":"Json Parsing Exception","detail":"The operation that you've provided couldn't be executed because of a parsing error from the JSON request body :javax.json.JsonException: Cannot auto-detect encoding, not enough chars. Verify that the syntax of the JSON text is valid before sending this request again.","o:ecid":"9a7808f96b85da4b:57b74198:14fc012fa7e:-8000-000000000006aebe, 0:23:1","o:errorCode":"MOBILE-16414","o:errorPath":"/internal-rt/------/bjhk","o:errorDetails":[{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1","title":"javax.json.JsonException","detail":"Cannot auto-detect encoding, not enough chars"}]}  please suggest the solution..

Hello, In MCS docs: to execute sql uri must point to: '/mobile/platform/database/sql' This is an example of how to execute sql with parameters.  
service.get('/mobile/custom/FIF_Incidents/incidents/count',
function(req, res) {
  var sql =
  'SELECT COUNT("incidentReport") "reportCount" ' +
  'FROM "FIF_Incidents" WHERE "status" = :status';
  var optionsList = {
  body: JSON.stringify({"status": req.query.status}),
  uri: '/mobile/platform/database/sql',
  headers: {
  'Content-Type': 'application/json',
  'Oracle-Mobile-SQL': sql
  }
  };
  req.oracleMobile.rest.post(optionsList,
  function(error, response, body) {
  var message = error ? error.message : body;
  res.status(response.statusCode).send(message);
  res.end();
  });
});
  regards,Ruben.

Related

Update operation on BO fails

Hey, I'm trying to perform an update operation on the data of a Business Object. But it fails. Can anyone please help with  this? require([    'operation/js/api/Conditions',    'operation/js/api/Operator'], function(Conditions, Operator) {    var so = Abcs.Entities().findById('SearchAccount');    var SendFlag = so.getProperty('sendToEloqua');    //var condition = Conditions.SIMPLE(SendFlag, Operator.EQUALS,'Y');    var operation = Abcs.Operations().update({  entity: so,         record: {   sendToEloqua: 'N'        } });   operation.perform().then(function(operationResult) {            if (operationResult.isSuccess()) {     alert("Updating Contact");   operationResult.getData().forEach(function(oneRecord) {        resolve("ok");   });        }  }).  catch(function(operationResult) {        if (operationResult.isFailure()) {             // Insert code you want to perform if fetching of records failed        }    });});
See the code sample in this blog for the way to update a value in a field:https://blogs.oracle.com/shay/oracle-abcs-traversing-relationships,-conditional-navigation,-query-and-update-with-javascript

Custom API - post Method

Hi, I created a custom API which has an endpoint with POST method to call a connector API ( connects to EBS R12). Here is the code I am using  service.post('/mobile/custom/ExpenseHeaderDetCust/HeaderDet', function (req, res) {   console.log('getting ready to call POST /mobile/custom/ExpenseHeaderDetCust/HeaderDet');  var sdk = req.oracleMobile;  var optionList = {  //uri: '/mobile/connector/ExpenseHeaderDetails'  };  var jsnObj = {  Body: {  "ExpenseCount": {  "#xmlns": "http://vis1225.dpebs-server.com:8000/webservices/rest/ExpenseCount/get_smart_exp_cnt_dtls_f",  "RESTHeader": {  "xmlns": "http://vis1225.dpebs-server.com:8000/webservices/rest/ExpenseCount/header",  "Responsibility": "SYSTEM_ADMINISTRATOR",  "RespApplication": "SYSADMIN",  "SecurityGroup": "STANDARD",  "NLSLanguage": "AMERICAN",  "Org_Id": "204"  },  "InputParameters": {  "P_REPORT_HEADER_ID": "37345"  }  }  }  };  optionList.body = JSON.stringify(jsnObj);  optionList.headers = {'Content-Type': 'application/json;charset=UTF-8'};  optionList.headers = {'oracle-mobile-backend-id': 'd838ab82-9755-4f54-bca1-38270afac134'};  optionList.headers = {'Authorization': 'SU5BTEdBUllUTVRSSUFMX0RFVkVMT1BNRU5UMV9NT0JJTEVfQU5PTllNT1VTX0FQUElEOkFyZzJlanZfc3oxcW1h'};    sdk.connectors.post('ExpenseHeaderDetails',optionList, function (error, response, body) {  if (error) {  res.send(response, error.message);  } else {  res.setHeader({'Content-Type': 'application/json;charset=UTF-8'});  res.send(200, body);  }  });  });}; And I get this error when I test the custom API with status code 500 {  "message": "Custom Code Problem in callback: [object Object]"} Can anyone help to figure out, what might be wrong?
Hi Pallavi Here's the MCS User Guide chapter for calling a connector which shows  POST example:https://docs.oracle.com/en/cloud/paas/mobile-cloud/mcsua/calling-mcs-apis-custom-code1.html#GUID-26DC731F-7C65-4209-95B2…  Here's one of the examples with some additions from myself to provide more information fitting your use case: service.get('/mobile/custom/incidentreport/weather/:city', function (req, res) {
  var body = {
    Header: {
      myHeader1: 'myValue1',
      myHeader2: 'myValue2'
    },
    Body: {
      GetWeather: {
      CityName: req.params.city,
      CountryName: 'Spain'
      }
    }
  };
  var optionList = {inType: 'json', versionToInvoke: '1.0'};
  req.oracleMobile.connectors.post('globalweather', 'GetWeather', body, optionList).then(
    function (result) {
      console.info("result is: " + result.statusCode);
      res.send(result.statusCode, result.result);
    },
    function (error) {
      console.info("error is: " + error.statusCode); 
      res.send(500, error.error);
    }
  );
});
 For this version of the code as it dynamically defines the connector name as a parameter 'globalWeather', has to pass in as part of the optionList the version of the connector to invoke version (versionToInvoke: '1.0'). The alternative is to refer to the connector name inline, which requires you to define the connector and its version as a dependency in the package.json file: service.get('/mobile/custom/incidentreport/weather/:city', function (req, res) {
  var body = {
    Header: {
      myHeader1: 'myValue1',
      myHeader2: 'myValue2'
    },
    Body: {
      GetWeather: {
        CityName: req.params.city,
        CountryName: 'Spain'
      }
    }
  };
  var optionList = {inType: 'json'};
  req.oracleMobile.connectors.globalWeather.post('GetWeather', body, optionList).then(
    function (result) {
      res.send(result.statusCode, result.result);
    },
    function (error) {
      res.send(500, error.error);
    }
  );
});
 Hope this gives you a spark of inspiration for how to write the code. Regards,CM.
Hi Chris, I have tried the same but getting the error- 500 with response-   {}.The response is null. Here is the code- service.post('/mobile/custom/ExpenseHeaderDetCust/HeaderDet', function (req, res) {         var sdk = req.oracleMobile;          var body = {            Header: {                'Accept': 'application/json',                'Content-Type': 'application/json',                'Authorization': 'Basic c3lzYWRtaW46b3JhY2xlMTI=',                'oracle-mobile-backend-id': 'd838ab82-9755-4f54-bca1-38270afac134',                'oracle-mobile-uitooling-backend-name': 'Test',                'oracle-mobile-uitooling-backend-version': '1.0'            },            Body: {                'ExpenseCount': {                    '#xmlns': 'http://vis1225.dpebs-server.com:8000/webservices/rest/ExpenseCount/get_smart_exp_cnt_dtls_f',                    'RESTHeader': {                        'xmlns': 'http://vis1225.dpebs-server.com:8000/webservices/rest/ExpenseCount/header',                        'Responsibility': 'SYSTEM_ADMINISTRATOR',                        'RespApplication': 'SYSADMIN',                        'SecurityGroup': 'STANDARD',                        'NLSLanguage': 'AMERICAN',                        'Org_Id': '204'                    },                    'InputParameters': {                        'P_REPORT_HEADER_ID': '37345'                    }                }            }        };        var optionList = {            inType: 'json'        };        sdk.connectors.ExpenseHeaderDetails.post('ExpenseCount', body, optionList).then(            function (result) {                res.send(result.statusCode, result.result);            },            function (error) {                res.send(500, error.error);            }        );    });
Can you look through the logs and see what is being recorded for the 500 error please?CM.
Hi Chris, here is the screenshot of log. 
Hmm, this doesn't reveal much.  Do any of the relating logs show a stack trace or similar? CM.
Hi Chris, I don't see any useful information to trace out this issue from the logs. Thanks,Pallavi.
Hi Pallavi, unfortunately we don't have enough information here to debug the problem, all we have is an error code.  I've reverted an email to Joe to find out if your a paid customer whereupon we can get an SR lodged for you, or a trial customer. CM.
Hi Chris, We are on the Trial Version of MCS.Can we raise an SR? Thanks,Pallavi
This is what I'm asking Joe. CM.
Hi Chris, I still couldn't trace out the issue.And didn't hear back from joe. The connector is working fine. The problem is in calling the connector from custom API for POST Method. Could you please give me any inputs to resolve this issue. Thanks,Pallavi.
We're trying to find a development resource who can give you sometime.  Please be patient.CM.
Thank you, Chris!

Unable to retrieve POST data

Hi, I am trying a Custom API implementation that supports both GET and POST (with the same single parameter)  I am able to retrieve the single GET parameter that I have successfully and can complete the connector based invocation. However, with the POST version the parameter comes back "undefined". When I examine the request body, it shows up fine. 
service.post('/mobile/custom/LocalWeatherAPI/CityWeather', function(req,res) {
  
var optionsList={uri: '/mobile/connector/LocalWeather'};
  
console.log('id received direct from params: '+req.body.id);
  
var city_id = req.body.id;
  
  
// build an object to describe the query parameters for the call
  
  
var queryObject={'id':''};
  
  
  
//THE BELOW IS NOT FOR POST PARAMETERS
  
//queryObject.id=req.params.id;
  
queryObject.id=city_id;
  
 
  
optionsList.qs=queryObject;
 
   
//handler function that is passed at the end of this function
   
//as part of the call to another API
   
var postHandler = function (error, response, body) {
       
console.log('HEADERS received from response: ' + JSON.stringify(response.headers));
 
       
response.setEncoding('utf8');
       
var responseMessage = body;
       
console.log(response.statusCode);
       
console.log(JSON.stringify(body));
       
if (error != null && error != undefined) {
           
responseMessage = error.message;
       
} else {
           
res.type('application/json');
       
}
       
res.status(response.statusCode).send(responseMessage);
       
res.end();
   
};
 
 
    var r=req.oracleMobile.rest.get(optionsList,postHandler);
    });
 
GET REQUEST (This is shown only for your information - this works)
---------------------
GET /internal-rt/mobile/custom/LocalWeatherAPI/CityWeather?id=524901 HTTP/1.1
oracle-mobile-api-version: 1.0
oracle-mobile-execute-etag: 17
Authorization: Basic SmFpZGV2VHJ1Y2tlcjpQKmR4STk4TVQqMg==
oracle-mobile-backend-id: 011593e1-555b-487d-8b24-b22a3a43f3ba
 
 
POST REQUEST (Does not work... as in it still returns a 200 response talks to the connector but the "id" data is not picked up in the custom code)
-----------------------------
 
 
POST /internal-rt/mobile/custom/LocalWeatherAPI/CityWeather?id=524901 HTTP/1.1oracle-mobile-api-version: 1.0oracle-mobile-execute-etag: 17Authorization: Basic SmFpZGV2VHJ1Y2tlcjpQKmR4STk4TVQqMg==oracle-mobile-backend-id: 011593e1-555b-487d-8b24-b22a3a43f3ba
id=524901
 
 Apologies if this is due to a lack of node.js knowledge. I have tried searching how the POST data can be retrieved and if "req.body" is not the way, please advise. TIA.
Hi User456456-OracleIt's likely your issue here is a nuance of the HTTP protocol, the HTTP parameters are also known as *query* parameters and by inference only make sense in a GET call.  In a POST call they are interpreted as part of the payload you're are trying to submit, not a query.As a result for a POST call HTTP parameters are treated different from a GET call, in that the HTTP parameters are carried in the body of the payload as you've discovered.  An explanation can be found on Stackoverflow: http://stackoverflow.com/questions/14551194/how-are-parameters-sent-in-an-http-post-requestIf you want to write one generic code block for both GET and POST, you'll need to also write code to detect what operation was invoked so you can interrogate the HTTP parameters in different locations.  You can detect the HTTP operation by calling req.route(), as explained in the Node Express documentation: http://expressjs.com/3x/api.html#req.routeRegards,CM.
Chris, Thanks for your reply. First off, my apologies for not posting the entire .js of the scaffold and also sending in "un-cleaned code".  I have since cleaned the code and modified it a wee bit further, but with no luck... 
module.exports = function(service) {
 
 
   /**  * The file samples.txt in the archive that this file was packaged with contains some example code.  */   service.get('/mobile/custom/LocalWeatherAPI/CityWeather', function(req,res) {
   var optionsList={uri: '/mobile/connector/LocalWeather'};
   var city_id = req.param('id');
 
   var queryObject={'id':''};
   queryObject.id=city_id;
   optionsList.qs=queryObject;
 
   //handler function that is passed at the end of this function  //as part of the call to another API    var getHandler = function (error, response, body) {
   console.log('HEADERS received from response: ' + JSON.stringify(response.headers));
 
  response.setEncoding('utf8');
   var responseMessage = body;
   console.log(response.statusCode);
   console.log(JSON.stringify(body));
   if (error != null && error != undefined) {
   responseMessage = error.message;
  } else {
  res.type('application/json');
  }
  res.status(response.statusCode).send(responseMessage);
  res.end();
  };
 
 
   var r=req.oracleMobile.rest.get(optionsList,getHandler);
  });
 
 
 
 
  service.post('/mobile/custom/LocalWeatherAPI/CityWeather', function(req,res) {
 
   console.log('body received: '+req.body.toString());
 
   //handler function that is passed at the end of this function  //as part of the call to another API    var postHandler = function (error, response, body) {
   console.log('HEADERS received from response: ' + JSON.stringify(response.headers));
 
  response.setEncoding('utf8');
   var responseMessage = body;
   console.log(response.statusCode);
   console.log(JSON.stringify(body));
   if (error != null && error != undefined) {
   responseMessage = error.message;
  } else {
  res.type('application/json');
  }
  res.status(response.statusCode).send(responseMessage);
  res.end();
  };
 
   var optionsList = {};
   optionsList.json = req.body;
   optionsList.uri = '/mobile/connector/LocalWeather';
   console.log('Options List JSON: '+optionsList.json);
  
   var r=req.oracleMobile.rest.post(optionsList,postHandler);
  });
 
};
 I do have a service.post and a service.get.   And it is able to route correctly when the request is a GET versus when it comes in as a POST (both of which I test from POSTMAN). The trouble is when it enters the POST, the req.body.id (basically my parameter is named "id") is just not found. It goes through to my connector as undefined and therefore fails. Am I retrieving the POST parameters correctly? (or am I still not understanding your reply?) Thanks.
I think the confusion was caused by my  var r=req.oracleMobile.rest.get(optionsList,postHandler); at the last line in my first code snippet yesterday. That was put only temporarily for testing with a "get". But I have since changed my code back to:  var r=req.oracleMobile.rest.post(optionsList,postHandler); [ONLY FOR YOUR INFORMATION]
I think the problem is while testing the POST method you are sending a non-json request body ( "id=524901" ) and the implementation tries to parse it as JSON (req.body.id  and optionsList.json = req.body). The solution is to either send a JSON payload in the request (  {'id':'524901'} ) or modify the POST implementation to parse the name value pair.
This seems like a likely reason for your problem It might be a good idea to set content-type to application/json in your POST.  2 reasons 1. You may need that header to allow your body to be parsed into a javascript object so you can reference it as req.body.id2. If you do that, I would expect a better error message when you post non-json or poorly formatted json If the suggestion above does not help, please share the body you are POSTing and the headers of the call you make in POSTMAN (if they are different from your initial post)

Understanding Promises....

Hi, In my custom API i want to make multiple http calls in from one function. I wll be directly calling the http request and not using connectors. I wanted to know how to use promise in such a case. Below is a snapshot of what i am trying to achieve var express = require('express');var bodyParser = require('body-parser');var request = require("request");var versionRoutes = require('express-routes-versioning')();var app = express();app.use(bodyParser.urlencoded({   extended: false}));app.use(bodyParser.json());module.exports = function (service) {   service.use(function (req, res, next) {   //req.version is used to determine the version   req.version = req.headers['accept-version'];   next();  });service.post('/mobile/custom/API/login', versionRoutes({   "1.0.0": doLogin  }));   function doLogin(req, res, next) {   authenticateUser()  .then(method1)  .then(method2)  .catch(function (errorResult) {   console.warn(errorResult);  });  }function authenticateUser(){ var options = { method: 'POST',  url: 'https://url/mobile/custom/login',  headers:   {     'accept-version': '1.0.0',     'oracle-mobile-backend-id': 'somethinghere' },  form:   { password: 'somethinghere',     login: 'somethinghere' } };request(options, function (error, response, body) {  if (error) throw new Error(error);  console.log(body);});}function method1(){  var options = { method: 'POST',  url: 'https://url/mobile/custom/data',  headers:    {      'accept-version': '1.0.0',     'oracle-mobile-backend-id': 'somethinghere' },  form:    { id: 'somethinghere',     context: 'somethinghere' } };request(options, function (error, response, body) {  if (error) throw new Error(error);  console.log(body);});}  function method2(){  }} When i run this in MCS i get the error 'Cannot read property 'then' of undefined' What am i missing here ? Also how to i use the result of 1st method as a parameter to the second method and so on Regards,
Since you're using the request module directly, and not any MCS api, promises are not automatically supported.  I suggest you start by taking a look at the request-promise api: https://github.com/request/request-promise 
Your method1 and method2 should return a Promise. First add.  var Promise = require('bluebird'); at the top of your code Make sure you return the promise from your functions.  function authenticateUser(){var options = { method: 'POST',  url: 'https://url/mobile/custom/login',  headers:   {     'accept-version': '1.0.0',     'oracle-mobile-backend-id': 'somethinghere' },  form:   { password: 'somethinghere',     login: 'somethinghere' } };return request(options, function (error, response, body);}function method1(){ var options = { method: 'POST',  url: 'https://url/mobile/custom/data',  headers:   {     'accept-version': '1.0.0',     'oracle-mobile-backend-id': 'somethinghere' },  form:   { id: 'somethinghere',     context: 'somethinghere' } };return request(options, function (error, response, body);}  function method2(){ function compareEtags(result) { //some code {  return Promise.reject({       statusCode: 412,//or some other code       error: "Precondition Failed"});  } else {  return Promise.resolve({     statusCode: 200     result:"some result"  });  } Hope that helps! Lonneke

How to capture HttpXMLRequest p.readyState in apex.server.process?

Hi I have code similar to the construct below and I need to detect if readyState==4. How do I do that? apex.server.process (   "my_ondemand_process",   {  x01: myId   },      {    dataType: "json",       success: function(pData) {    }   }); Can anyone please offer some help? Cheers- H
Hi, You can use complete or success callback
apex.server.process(
"my_ondemand_process",
{x01: myId},  
{dataType: "json",
  success: function(pData){/* execute this code when call ends succesfully */},
  complete: function(){/* execute this code when call ends to any status */}
}
);
 Regards,Jari
Hi Jari - Thanks!

Categories

Resources