I am making a phonegap app for android. I am receiving a json string and trying to parse it . It's a very small data.
{"result":{ "node":"32"}
}
if iam using alert(request.responseText)
the result is displayed but if i return this request.responseText to the calling function and collect it there in a variable like var x= somefunction(); x contains undefined.
var jsonObj = sendPostRequest(url,nurl);
console.log(jsonObj+""); // GIVES UNDEFINED HERE AT THIS LINE BUT SAME STATEMENT WORKS IN sendPostRequest()
if(jsonObj){
var Json = JSON.parse(jsonObj);
console.log(json);
document.getElementById("gnodei").innerHTML= json.result.wEventId;
}
I can collect this response in a variable y inside somefunction() but on returning this data to the calling function nothing reaches there. I use the above json data x just below it but it doesn't work.
please suggest.
edit: `function sendPostRequest(url,nurl){
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0){
console.log(request.status);
//alert(request.responseText);
var txt= request.responseText;
console.log(txt);
return txt;
}
}
}
request.open("POST",url, true);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send(nurl);
}`
The ajax call. Also there are multiple functions calling this ajax call after preparing their url and nurl values so i need this function as it is. I only need to know how to get back the response in my calling function.
Thanks
Solved it: Created a function to be passed as callback to the sendPostRequest(url,nurl) method. This callback is called only after the ajax call finishes as correct status. The callback function assigns the data that can be used thereafter.
you can use:
var jsonData = $.parseJSON(stringJson);
Related
My API response:
{
success: true,
msg: 'Custom Success Message',
data : [Objects]
}
And in case of failure, the response is:
{
success: false,
msg: 'Custom Error Message',
data: null
}
My question is how do I handle the data parameter in retrofit for both the scenarios?
The app crashes if success is false and data is null.
As per my experience, you must have to tell to the API Developer to make API with some structure.
Two ways:
There is must be blank array if no data available for data key.
data key must not be there if no data available.
Reason:
data key is giving you array, retrofit gson automatically converts that data to your model class but if you will get null then it will be confused to convert.
Key Point: There is no need to do logical programming by Android Developer
Well actually retrofit has no option to handle 2 type of response handle.
You can ask your backend developer to send null data even with the same type for example.
on Success case data:[String,String]
And
on Failure case data:[]
If you are not using third party api or cannot contact backend guy.
Here is how you can tackle this situation.
While on getting result callback use try and catch using retrofit exception. To play save with hasUnresolvableType
Just find out which exception you are facing.
please check the below code for check null condition of while getting a response.
call1.enqueue(new Callback<YourModelClass>()
{
#Override
public void onResponse (Call < YourModelClass > call, Response < YourModelClass > response){
// this line must be write
if (Response.body != null) {
// try this code
JSONObject reader = new JSONObject("your response");
JSONArray data = reader.getString("data");
if(data!=null)
{
}
}
}
}
Make Changes in your API
If data is null the return
{
success: false,
msg: 'Custom Error Message',
data: [] // This is blank array.
}
if data is not null then return
{
success: true,
msg: 'Custom Success Message',
data : [Objects]
}
I want to use variable defined in inAppBrowser of cordova and use it in in executeScript method?
ref = cordova.InAppBrowser.open(env,'_blank','clearcache=no,location=no,
clearsessioncache=no, footer=no,zoom=no' );
var variable_needed = 1;
ref.addEventListener("loadstop", function(e) { ref.executeScript({
code: "console.log(variable_needed);"})
});
When I am trying to access varible_in executescript, it gives NULL.
I know they are different javascript bundle. Is there any way to achieve this?
The value passed via the code key of executeScript() is passed as a string to the Java layer which injects it into the Webview of the Inappbrowser and eval()'s it.
As such, there is no direct "connection" between the Cordova app Webview and the InappBrowser Webview that would allow Javascript entities to be directly shared.
Since the data is passed as a string, only stringifiable Javascript data can be passed (i.e. not functions).
In your case above, the variable value should simply be inlined in the code string:
ref = cordova.InAppBrowser.open(env,'_blank','clearcache=no,location=no, clearsessioncache=no, footer=no,zoom=no' );
var variable_needed = 1;
ref.addEventListener("loadstop", function(e) {
ref.executeScript({
code: "console.log("+variable_needed+");"
});
});
However if you want to send a more complex object structure you would need to stringify it, for example:
ref = cordova.InAppBrowser.open(env,'_blank','clearcache=no,location=no, clearsessioncache=no, footer=no,zoom=no' );
var myObj = {
foo: "bar"
};
var s_myObj = JSON.stringify(myObj);
ref.addEventListener("loadstop", function(e) {
ref.executeScript({
code: "var myObj = JSON.parse('"+s_myObj+"'); console.dir(myObj);"
});
});
I have a retrofit function for which i make call from various activities and fragments, which produces same output type. for simple example
retrofitService.fetchData().enqueue(new Callback<MyData>{})
since i am going to call the same function from different activities i created a separate common call back interface
interface OnDataFetch(){
// where mydata holds the response body on success
// msg is response.ErrorBody when the response code is not 200
// resonseType = 0 for success
// responseType = 1 for response code other than 200
// reponstType = 1 for on failure
public void dataFetched(Data mydata,ErrorMsg msg, int responseType);
}
now on on response and on failure i call the dataFetched();
onSuccess(.....){
response.isSuccessful(){
responsetType = 0;
Data mydata = response.body();
}else{
//when response code is not 200 we get error msg from server
responstType = 1;
mydata = null;
ErrorMsg msg = Gson.from(response.ErrorBody(),ErrorMsg);
}
dataFetched(mydata,msg,responseType);
}
onFailure(....){
responseType = 2;
dataFetched(null,null,responseType);
}
now all those activities which require mydata implements the dataFetched interface. Hence i am separating retrofit logics into separate class. Is this the right way to simplify activities with REST API calls or is there some there better way to do the same. Later may be i will store those response to sql database, take that also into consideration while answering thanks(Don't care about syntax).
I am working on a project where I need to download a javascript and use it to calculate some values. This is already working on iOS so the javascript seems to be just fine.
Here is the stripped down javascript (I have removed the content as I do not own the script):
var resultArray = [];
function calculateRemainingAmountForForecastWeeks(numberOfWeeks, weeklyDisposable, easing, safetyZone, safetyZoneEasing, overSpentThisWeek) {
// Some calculations...
resultArray[numberOfWeeks] = spentBeyondForecast;
}
I am using Rhino and here is what I do:
org.mozilla.javascript.Context rhino = org.mozilla.javascript.Context.enter();
rhino.setOptimizationLevel(-1);
try {
Scriptable scope = rhino.initStandardObjects();
rhino.evaluateString(scope, WeeklyApplication.getCalculatorJS(), "JavaScript", 0, null);
Object obj = scope.get("calculateRemainingAmountForForecastWeeks", scope);
if (obj instanceof Function) {
Function jsFunction = (Function) obj;
// Call the function with params
Object[] params = new Object[]{numberOfWeeks, weeklyDisposable, easing, safetyZone, safetyZoneEasing, overSpentThisWeek};
Object jsResult = jsFunction.call(rhino, scope, scope, params);
// Parse the jsResult object to a String
String result = org.mozilla.javascript.Context.toString(jsResult);
Log.d(TAG, "SKN-calculate3=" + result);
}
} finally {
org.mozilla.javascript.Context.exit();
}
I know it is not the most optimized use of scope here, but I just need to get it working first. I keep getting "undefined" in the result String, what am I doing wrong here?
And when I do get this working, how do I then get the values stored in the "resultArray"?
Thank you
Søren
From code that you posted, it looks like function calculateRemainingAmountForForecastWeeks() doesn't return anything, so it's ok to get Undefined from it.
Getting value from resultArray is easy, as it's just a field in your scope scriptable object:
Object[] params = new Object[]{numberOfWeeks, weeklyDisposable, easing, safetyZone, safetyZoneEasing, overSpentThisWeek};
// function doesn't return anything
jsFunction.call(rhino, scope, scope, params);
NativeArray resultArray = (NativeArray) scope.get("resultArray", scope);
double result = ((Number) resultArray.get(numberOfWeeks)).getDoubleValue();
Log.d(TAG, "SKN-calculate3=" + result);
Note: of course, I don't know what your types are, so probably you'd have to update this snippet to make it work for you.
I have used Google Api in order to retrive places details but Google Api only returns 20 results at a time according to category. JSON parsed text contains next_page_token which have referance that could be used to retrive another page containing results and so on. My question is how to put parsing in loop so that i can get all the total results.
So you have to build up a list of all results, but not invoke your callback until all results are downloaded. In the code below, we keep calling the function to get the next page of results until the next_page_token isn't available, in which case we've loaded all results and can invoke our callback function.
var jsonresults = [];
function getPlacesResults(url, callback) {
var xhr = Ti.Network.createHTTPClient({...});
xhr.onload = function (data) {
var json = JSON.parse(data);
jsonresults.push(json)
if (json.next_page_token) {
//assumes next_page_token is a url we can pass in
getPlacesResults(json.next_page_token, callback);
} else {
callback(jsonresults);
}
}
xhr.open('GET', url);
xhr.send();
}
//used like so
getPlacesResults('http://www.google.com/whatever', function (allResults) {
//...do stuff with all of your results here.
});