I have built function that checks if record exist in local storage, if not trigger ajax call to get the data. Once data is returned I set the data in local storage. After this function completes I have to pass the data to another function that will feed the data in the form. I'm wondering what is the best practice now days to achieve this? I see more object oriented JavaScript now days and I'm wondering if any of OOP methods can be applied in this case. Here is example of my fucntion:
function getData(fnName,storageID,recID){
var inStorage = localStorage.hasOwnProperty(storageID) ? true : false,
frmData;
if(inStorage) {
frmData = JSON.parse(localStorage.getItem(storageID));
}else{
$.ajax({
type: 'POST',
url: 'AjaxFunctions.cfc?method='+fnName,
data: {'recID':recID},
dataType: 'json',
async: false
}).done(function(obj){
if(obj.STATUS == "200"){
var storageData = $.isEmptyObject(obj.DATA) ? null : JSON.stringify(obj.DATA);
localStorage.setItem(storageID,storageData);
frmData = storageData;
}else{
$('#error').html(obj.MESSAGE);
}
}).fail(function(jqXHR, textStatus, errorThrown){
alert("Error: "+errorThrown);
});
}
//frmFeed(frmData);
return frmData;
}
Function above once completed should pass the data in another function that will populate the form:
function frmFeed(frmData){
//Loop over frmData and populate the fields
}
I know the one way to accomplish this is to simply call frmFeed inside getData function that I showed above (commented code). is there any other way to call frmFeed and pass the data? If anyone can provide some example please let me know. Thank you!
There are several ways:
Callbacks
Promises
Not recommended would be to use synchronous ajax requests because it will block the UI.
Here's an implementation using promises:
function getData(fnName,storageID,recID){
return new Promise(function(resolve, reject) {
var inStorage = localStorage.hasOwnProperty(storageID) ? true : false;
if (inStorage) {
resolve(JSON.parse(localStorage.getItem(storageID)));
} else {
$.ajax({
type: 'POST',
url: 'AjaxFunctions.cfc?method='+fnName,
data: { 'recID': recID },
dataType: 'json'
// removed sync
}).done(function(obj){
if(obj.STATUS == "200"){
var storageData = $.isEmptyObject(obj.DATA) ? null : JSON.stringify(obj.DATA);
localStorage.setItem(storageID,storageData);
resolve(storageData);
}else{
$('#error').html(obj.MESSAGE);
// or reject here
reject(obj);
}
}).fail(function(jqXHR, textStatus, errorThrown){
alert("Error: "+errorThrown);
// or reject may be better here
reject({ 'jqXHR': jqXHR, 'textStatus': textSTatus, 'errorThrown': errorThrown });
});
}
});
}
getData('blah', 'storageId', 'recId')
.then(function(frmData) {
frmFeed(frmData);
});
Related
I am really new to CefSharps Chromium browser and have difficulty figuring out how to get the result of a jquery ajax request.
My first attempt was to pass my AJAX requesto to EvaluateScriptAsync. In fact the script works. It does exactly what I want, but I do not get any results/status codes, because my Cef-Task does not wait until AJAX has completed its work.
Here an example (just a sample code):
var tasks = pdBrowser.EvaluateScriptAsync(#"
(function(){
$.ajax({
type: ""POST"",
dataType: ""json"",
cache: false,
url: ""_resources/php/ajaxRequests.php"",
async: false,
data: {
action: ""insertCrossPlatform"",
type: """",
values: JSON.stringify(""foo bar"")
},
success: function(response) {
if (typeof response === 'string' && response.substring(0, 5) == ""ERROR"")
{
return response;
}
else
{
//pageReload();
return ""OK"";
}
},
error: function(xhr, textStatus, errorThrown) {
return errorThrown + ""\n"" + xhr.responseText;
},
complete: function() {
return ""COMPLETE"";
}
});
})();", null);
tasks.ContinueWith(t =>
{
if (!t.IsFaulted)
{
var response = t.Result;
if (response.Success)
{
if (response.Result != null)
{
MessageBox.Show(response.Result.ToString());
}
}
else
{
MessageBox.Show(response.Message, "Ein Fehler ist aufgetreten", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}, TaskScheduler.Default);
Afterwards I have read that there is a SchemeHandler, but I do not properly understand how to implement it. Can anyone help me out?
Thanks in advance.
Firstly SchemeHandler is unlikely to be suitable in this scenario, you would typically implement a SchemeHandler when your providing the response.
Most people choose to bind an object, and call a method on their bound object when they wish to communicate with the parent application. See the FAQ for an example. https://github.com/cefsharp/CefSharp/wiki/Frequently-asked-questions#3-how-do-you-expose-a-net-class-to-javascript
With 49.0.0 you can implement ResponseFilter to gain access to the underlying response buffer, it's complex and not well documented, so if your not comfortable digging through reference C++ code then this option isn't for you. Here's a reference https://github.com/cefsharp/CefSharp/blob/cefsharp/49/CefSharp.Example/Filters/PassThruResponseFilter.cs#L17
Something that I did was create an element on the page through javascript with an ID that is the response of the ajax call. So for example, when you make an ajax call assign an ID to the ajax call.
When the ajax call returns, write an element on the page with the pre-assigned id and callback information. Then you can just use cefsharp to read the element content from the page and this will be your callback information.
var myDivElement =document.getElementById('textareaInfo');
if( myDivElement === null)
{
var input = document.createElement('textarea');
input.id = "textareaInfo";
input.value = "Test"
input.rows="4";
input.cols="50";
input.style="height:100%;width:900px;"
var dom = document.getElementsByClassName("page-body")[0];
dom.insertAdjacentElement('afterbegin', input)
}
Then later with ajax
var root = 'https://jsonplaceholder.typicode.com';
var _holder = callbackObj;
callbackObj.showMessage(""ajax"");
$.ajax({
url: root + '/posts/1',
contentType: 'application/json; charset=utf-8',
method: 'GET',
complete: function(data){
},
success: function(response) {
$(#'textareaInfo').value(response);
}
}).then(function(data) {
callbackObj.showMessage(data);
});
Then read the texarea from cefsharp in c#
chromeBrowser.GetMainFrame().EvaluateScriptAsync(function()...$(textareaInfo).value).Result
You can use PostMessage javascript method to notify .NET application:
CefSharp.PostMessage('Your data Here');
Here is .NET code example for headless browser:
var browser = new ChromiumWebBrowser("", null, RequestContext);
browser.JavascriptMessageReceived += (sender, e) =>
{
if ((string)e.Message.notificationid == "notification1")
{
// Your processing code goes here
}
};
browser.Load(destinationUrl);
browser.ExecuteScriptAsync("(function() { ... ; CefSharp.PostMessage({data: data, notificationid: 'notification1'});})()");
I have an app that needs three different post requests to sync data, I only want one thing to happen when all three are completed but the jquery when is not working. All posts use the success function to process data that the server sent back. Here is my code:
var picUploads = $.post("http://www.epcmapp.co.za/php2/uploadPic.php", {Images: jsonPics}, function (res) {
alert("Ajax Images return");
if(res != "" && res != "53554343455353")
alert(res);
});
var pdfUploads = $.post("http://www.epcmapp.co.za/php2/uploadPDF.php", {PDFs: jsonPDF}, function (res) {
alert("Ajax PDF return");
if(res != "" && res != "53554343455353")
alert(res);
});
var sync = $.post("http://www.epcmapp.co.za/php2/sync.php", {data: json}, function (res) {
alert("Ajax return");
var result = JSON.parse(res);
dropSyncTables();
checkDB();
for (var i in result) {
populateDB(result[i].toString());
}
readDB();
loadProjects();
loadAdditional();
loadProcessRows();
loadAttachments();
});
$.when(picUploads, pdfUploads, sync).then(function() {
$("#loadIcn").attr("src", "images/check3.png");
});
The alerts in the posts do not pop up and the code inside the jquery then never runs. How am I supposed to do this then?
If you need a failure function, you can't use the $.get or $.post functions; you will need to call the $.ajax function directly. You pass an options object that can have "success" and "error" callbacks.
Instead of this:
$.post("/post/url.php", parameters, successFunction);
you would use this:
$.ajax({
url: "/post/url.php",
type: "POST",
data: parameters,
success: successFunction,
error: errorFunction
});
There are lots of other options available too. The documentation lists all the options available.
ref This answer
First check your console.log. You would probably find the issue there. But even if you find it you would always want some kind of errorhandling and this is possible with the deffered objects:
$.when(picUploads, pdfUploads, sync)
.then(function() {
$("#loadIcn").attr("src", "images/check3.png");
})
.fail(function(ts) {
alert('something failed');
console.log(ts.responseText); //Check in console what went wrong here
})
It is also possible to use done() and fail() with $.post (as of jQuery 1.5)
var picUploads = $.post("http://www.epcmapp.co.za/php2/uploadPic.php", {Images: jsonPics}, function (res) {
alert("Ajax Images return");
if(res != "" && res != "53554343455353")
alert(res);
})
.done(function() {
alert( "second success" );
})
.fail(function() {
alert( "error" );
});
I am running in to some interesting situation. on my application I have couple of situations.
1. I have to grab data from two different sources.(for that i have used ajax call).
2. I have to manipulate those data comparing to each other. if both are equal than third array will gets the value input from first array first array. and Eventually i have to return the third value and work on my graphs.
so for that I have :
getData : function(){
var bubbleArray= [];
var companyData=[];
var managerData =[];
$.ajax({
async: false,
url: "data/companyData.json",
dataType: "json",
success: function (bubbleJsonData){
$.each (bubbleJsonData.main.DATA_RECORD, function(index, response){
if(response.C_HRS!=0&&response.D_CUST_HRS!=0){
companyData.push([(response.C_HRS/442)*100, (response.D_CUST_HRS/442)*100, ((response.D_CUST_HRS/response.C_HRS)*100), response.C_HRS, response.D_CUST_HRS, response.CPY_NAME ]);
}
});
},
error: function(jqXHR, textStatus, errorThrown){
alert("Error:"+ errorThrown);
}
//ajax call to get the managerData.
$.ajax({
async: false,
url: "data/managerData.json",
dataType:"json",
success: function(managerjsonData){
$.each (managerjsonData.main.DATA _RECORD, function(index, responsedata){
if(responsedata.CPY_NAME!=""){
managerData.push([responseData.CPY_NAME]);
}
});
},
error: function(jqXHR, textStatus, errorThrown){
alert("Error:"+ errorThrown);
}
});
});
now, I have to compare the managerData. CPY_NAME with companyData.CPY_NAME if the match found generate the bubbleArray with the details of companyData means bubbleArray should have C_HRS, D_CUST_HRS,..........
if any help available form anybody would be highly appreciated
You need to wait until both the requests finish and save their results in some variable, and then compare them.
var yourAjaxRequests = [];
var jqXHR = $.ajax();
yourAjaxRequests.push(jqXHR);
$.when.apply($, yourAjaxRequests).done(function() {
/* compare logic here */
);
I have two problems here, 1st the code below won't work, anybody could tell me what am i missing? 2nd, i want to return the value from php to success function and then that value also will be returned to the parent function...
function myFunc(e){
$.ajax({
type: "post",
url: "path/myPhp.php",
data: "val="+e,
dataType: "php",
success: function(result){
return result; //i want this result to be returned to parent function myFunc(e)
},
error: function(e){
alert('Error: ' + e);
}
});
}
There is no data type named php for jquery ajax.
legal data type is as below:
xml
html
script
json
jsonp
text
Do you mean "json" data type?
If you want your response to return as function return value, then you need to make it ajax synchronize and later ajax unsynchronize after ajax finish
If your return response is not array ,then I think this will work.
function myFunc(e){
var returnValue = '';
$.ajaxSetup({async:false}); // synchronize
$.ajax({
type: "post",
url: "path/myPhp.php",
data: "val="+e,
success: function(result){
returnValue = result;
},
error: function(e){
alert('Error: ' + e);
}
});
$.ajaxSetup({async:true});// Unsynchronize
return returnValue;
}
1) You have an invalid value in 'dataType'. Valid values are: xml, json, script, or html.
2) As I see it, you want the ajax call to behave in a synchronous way.
Use 'async: false' to accomplish that. Try:
function myFunc(e){
var value = "";
$.ajax({
type: "post",
url: "path/myPhp.php",
data: "val="+e,
dataType: "json",
success: function(result){
value = result;
},
error: function(e){
alert('Error: ' + e);
},
async: false // set synchronous
});
alert(value); // use value
}
Or
$.ajaxSetup({async:false});
before issuing $.ajax() call.
A discussion about using synchronous ajax can be found here How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?
I am developing a heavily scripted Web application and am now doing some Error handling. But to do that, I need a way to access the AJAX parameters that were given to jQuery for that specific AJAX Request. I haven't found anything on it at jquery.com so I am asking you folks if you have any idea how to accomplish that.
Here is an example of how I want to do that codewise:
function add_recording(filename) {
updateCounter('addRecording','up');
jQuery.ajax({
url: '/cgi-bin/apps/ajax/Storyboard',
type: 'POST',
dataType: 'json',
data: {
sid: sid,
story: story,
screen_id: screen_id,
mode: 'add_record',
file_name: filename
},
success: function(json) {
updateCounter('addRecording','down');
id = json[0].id;
create_record(id, 1, 1, json);
},
error: function() {
updateCounter('addRecording','error',hereBeData);
}
})
}
hereBeData would be the needed data (like the url, type, dataType and the actual data).
updateCounter is a function which updates the Status Area with new info. It's also the area where the User is notified of an Error and where a Dismiss and Retry Button would be generated, based on the Info that was gathered in hereBeData.
Regardless of calling complete() success() or error() - this will equal the object passed to $.ajax() although the values for URL and data will not always be exactly the same - it will convert paramerters and edit the object around a bit. You can add a custom key to the object to remember your stuff though:
$.ajax({
url: '/',
data: {test:'test'},
// we make a little 'extra copy' here in case we need it later in an event
remember: {url:'/', data:{test:'test'}},
error: function() {
alert(this.remember.data.test + ': error');
},
success: function() {
alert(this.remember.data.test + ': success');
},
complete: function() {
alert(this.remember.data.url + ': complete');
}
});
Of course - since you are setting this data originally from some source - you could rely on the variable scoping to keep it around for you:
$("someelement").click(function() {
var theURL = $(this).attr('href');
var theData = { text: $(this).text(); }
$.ajax({
url: theUrl,
data: theData,
error: function() {
alert('There was an error loading '+theURL);
}
});
// but look out for situations like this:
theURL = 'something else';
});
Check out what parameters you can get in the callback for error.
function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
You can use the ajax complete event which passes you the ajaxOptions that were used for the request. The complete fires for both a successful and failed request.
complete : function (event, XMLHttpRequest, ajaxOptions) {
//store ajaxOptions here
//1 way is to use the .data on the body for example
$('body').data('myLastAjaxRequest', ajaxOptions);
}
You can then retireve the options using
var ajaxOptions = $('body').data('myLastAjaxRequest');