How to trim JSON Object removing whitespace - javascript

I hava a common ajax.post method which accepts data from function parameter. Now i want to trim the properties of data. Below is the code.
function PostToServer(options) {
var defaults = {
'url': null,
'data': null,
'onSuccess': null,
'onError': null
};
var parameters = $.extend(defaults, options);
$.ajax({
url: parameters.url,
type: "POST",
data: JSON.stringify(parameters.data),
contentType: "application/json",
success: function (res) {
if ($.isFunction(parameters.onSuccess)) {
parameters.onSuccess(res);
}
},
error: function (xhr, status, error) {
if ($.isFunction(parameters.onError)) {
parameters.onError(xhr, status, error);
}
}
});
}
Now in this function i want to trim the 'parameters.data' object so that it removes whitespace from both ends. but i dont know what comes in 'parameters.data' so i can not access its properties and use trim function.
Please help.

Try this:
$.each(res, function(index) {
var that = this;
$.each(that, function(key, value) {
var newKey = $.trim(key);
if (typeof value === 'string')
{
that[newKey] = $.trim(value);
}
if (newKey !== key) {
delete that[key];
}
});
});

Related

callback in jquery ajax not working when using jquery ajax cache code below

Below is my code and issue is with cache code is not working properly if any ajax call has callback in success.
var localCache = {
/**
* timeout for cache in millis
* #type {number}
*/
timeout: 30000,
/**
* #type {{_: number, data: {}}}
**/
data: {},
remove: function (url) {
delete localCache.data[url];
},
exist: function (url) {
return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
},
get: function (url) {
console.log('Getting in cache for url' + url);
return localCache.data[url].data;
},
set: function (url, cachedData, callback) {
localCache.remove(url);
localCache.data[url] = {
_: new Date().getTime(),
data: cachedData
};
if ($.isFunction(callback)) callback(cachedData);
}
};
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
var complete = originalOptions.complete || $.noop,
url = originalOptions.url;
//remove jQuery cache as we have our own localCache
options.cache = false;
options.beforeSend = function () {
if (localCache.exist(url)) {
complete(localCache.get(url));
return false;
}
return true;
};
options.complete = function (data, textStatus) {
localCache.set(url, data, complete);
};
}
});
function handleAjaxRequests(url, parameters, headers, method, successHandler, options, errorHandler) {
if (typeof (method) === 'undefined') {
method = "GET";
}
if (typeof (headers) === 'undefined') {
headers = "";
}
if (typeof (parameters) === 'undefined') {
parameters = "";
}
successHandler = typeof (successHandler) === 'undefined' ? function (data) {} : successHandler;
errorHandler = typeof (errorHandler) === 'undefined' ? function (data) {} : errorHandler;
return $.ajax({
method: method.toUpperCase(),
url: url,
// async: false,
data: parameters,
headers: headers,
success: function (data) {
console.log('hi');
successHandler(data, options);
console.log('bye');
},
error: function (data) {
$('.loader').hide();
errorHandler(data);
},
});
}
As per the above code after successfully run ajax successHandler(data, options);function should be the trigger but it not due to above cache handler code. I have no idea why this is not working. If I write simple something rather than callback function it is working. Same issue with datatable Ajax callbacks.
I have to use above cache handler at global level in my project doesn't matter ajax request is from datatable or from any other source.
Above cache code is from here https://stackoverflow.com/a/17104536/2733203
As discussed in the chatroom I've made some changes in your code :
var localCache = {
/**
* timeout for cache in millis
* #type {number}
*/
timeout: 30000,
/**
* #type {{_: number, data: {}}}
**/
data: {},
remove: function(url) {
delete localCache.data[url];
},
exist: function(url) {
return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
},
get: function(url) {
console.log('Getting in cache for url ' + url);
return localCache.data[url].data;
},
set: function(url, cachedData, callback) {
localCache.remove(url);
localCache.data[url] = {
_: new Date().getTime(),
data: cachedData
};
console.debug('caching data for '+url, cachedData);
if ($.isFunction(callback)) callback(cachedData);
}
};
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
if (options.cache) {
var complete = originalOptions.complete || $.noop,
url = originalOptions.url;
//remove jQuery cache as we have our own localCache
options.cache = false;
options.beforeSend = function() {
if (localCache.exist(url)) {
console.log('using cache, NO QUERY');
complete(localCache.get(url));
return false;
}
console.log('sending query');
return true;
};
options.complete = function(data, textStatus) {
localCache.set(url, data, complete);
};
}
});
function handleAjaxRequests(url, parameters, headers, method, successHandler, options, errorHandler) {
method = method || "GET";
headers = headers || {};
parameters = parameters || {};
return $.ajax({
method: method.toUpperCase(),
url: url,
cache: true,
// async: false,
data: parameters,
headers: headers,
success: successHandler,
error: errorHandler,
});
}
handleAjaxRequests('/echo/json/', {p1: 'hey'}, null, 'POST', function(data){console.log('first success without cache', data);});
setTimeout(function(){
handleAjaxRequests('/echo/json/', {p1: 'hey'}, null, 'POST', function(data){console.log('success! with cache hopefully', data);});
}, 2000);
Fiddle here
added some logs in the localCache methods to see what's happening. Cache is never used so I've added the missing cache:true option
Added some logs inside beforeSend method to monitor the toggle between cache and query. Everything works fine.
Cleaned up the arguments null checks and removed empty function(){} (use $.noop() instead btw.
Now the core of your issue. The callbacks errorHandler and successHandler are arguments. $.ajax is asynchronous! it means at some point of the execution, right after this call is made, you won't be sure if the variable has the same value. Easiest solution is to just reference the function directly and let jQuery do the scope management. Hardest solution would be to give these functions to the context option in ajax settings which I don't recommend.
Now, the solution you use allows you to directly call $.ajax without a wrapper method. Why don't you use it directly? simpler and less prone to errors
EDIT: I'm really not fond of context so there is another alternative.
function handleAjaxRequests(url, parameters, headers, method, successHandler, options, errorHandler) {
method = method || "GET";
headers = headers || {};
parameters = parameters || {};
return $.ajax({
method: method.toUpperCase(),
url: url,
cache: true,
// async: false,
data: parameters,
headers: headers,
success: (function(handler, opt) {
return function( /*Anything*/ data, /*String*/ textStatus, /*jqXHR*/ jqXHR) {
console.log('hi');
handler(data, opt);
console.log('bye');
};
})(successHandler, options),
error: (function(handler, opt) {
return function( /*jqXHR*/ jqXHR, /*String*/ textStatus, /*String*/ errorThrown) {
console.log('ouch');
handler(errorThrown);
};
})(errorHandler, options),
});
}
You scope the function with this well known javascript trick aka currying.
New fiddle here.
EDIT 2: if you want successHandler to run even when getting from cache you should use complete instead of success
function handleAjaxRequests(url, parameters, headers, method, successHandler, options, errorHandler) {
method = method || "GET";
headers = headers || {};
parameters = parameters || {};
return $.ajax({
method: method.toUpperCase(),
url: url,
cache: true,
// async: false,
data: parameters,
headers: headers,
complete: (function(handler, opt) {
return function( /*Anything*/ data, /*String*/ textStatus, /*jqXHR*/ jqXHR) {
console.log('hi');
handler(data, opt);
console.log('bye');
};
})(successHandler, options),
error: (function(handler, opt) {
return function( /*jqXHR*/ jqXHR, /*String*/ textStatus, /*String*/ errorThrown) {
console.log('ouch');
handler(errorThrown);
};
})(errorHandler, options),
});
}
Fiddle here.

How to Implement function return from http request

I have an ajax call as follow
$.ajax({
datatype:'json',
url: 'http://localhost:9090/openidm/policy/managed/user/'+storeUserId,
type:'get',
xhrFields: {
withCredentials: true
} ,
corssDomain:true,
headers: {
"X-Requested-With":"XMLHttpRequest"
},
success: function (result){
var validations = result.properties[1].policies[1];
console.log(validations.policyFunction);
},
error:function (error){
console.log (error);
}
});
});
The above ajax call return the policyFunction as follow :
function (fullObject, value, params, property) {
var isRequired = _.find(this.failedPolicyRequirements, function (fpr) {
return fpr.policyRequirement === "REQUIRED";
}), isNonEmptyString = (typeof (value) === "string" && value.length), hasMinLength = isNonEmptyString ? (value.length >= params.minLength) : false;
if ((isRequired || isNonEmptyString) && !hasMinLength) {
return [{"policyRequirement":"MIN_LENGTH", "params":{"minLength":params.minLength}}];
}
return [];
}
i wanna to implement that function in my javascript file. Like passing parameters to that function. So how can i implement.
You can invoke it in the browser like so:
policyFunction = eval("(" + validations.policyFunction + ")");
failures = policyFunction.call({ failedPolicyRequirements: [] },
fullObject,
value,
params,
propertyName);
Where fullObject is the entire object, value is the value of the particular property, params are any parameters needed within the validation function, and propertyName is the name of the property.

External method from an AJAX callback in JavaScript & jQuery

I have a function in JS & jQuery that fires an AJAX call and it has a callback block to let me know when it's finished:
function ajaxCall(url, type, dataType, dataToSend, callback) {
if (dataType == undefined) dataType = "json";
if (dataToSend == undefined) dataToSend = null;
$.ajax({
url: url,
type: type,
dataType: dataType,
contentType: "application/json",
data: dataToSend,
async: true,
success: function (result) {
callback(result);
},
error: function (data, status) {
console.error("Server Error: " + status);
}
});
}
I am accessing it like so, but using external functions like showAjaxLoader() just doesn't work! it says this function is undefined:
function registerUser(data) {
ajaxCall(pathServiceRegister, "POST", undefined, JSON.stringify(data), function (result) {
// SOME CODE THAT RUNS WHEN IT'S COMPLETE
// External method:
showAjaxLoader(false); // Doesn't work
});
});
function showAjaxLoader(show) {
var loader = $('.ajax-loader');
if (show) {
loader.fadeIn("fast");
} else {
loader.fadeOut("fast");
}
}
What am I doing wrong?
Thanks :)
Worked out some sample. this may be good practice. Try this :
$(document).ready(function() {
$("button").click(function() {registerUser();});
});
var Scallback = function(arg) {
alert("Success :"+arg);
showAjaxLoader(true);
}
var Ecallback = function(arg) {
alert("Err :"+arg);
showAjaxLoader(true);
}
function showAjaxLoader(show) {
var loader = $('.ajax-loader');
if (show) {
loader.fadeIn("fast");
} else {
loader.fadeOut("fast");
}
}
function ajaxCall(url, type, Scallback, Ecallback) {
$.ajax({
url : url,
type : type,
async : true,
success : function(result) {
Scallback(result);
},
error : function(data) {
Ecallback(data)
}
});
}
function registerUser()
{
ajaxCall(pathServiceRegister, "GET", Scallback, Ecallback);
}
Have you tried to do something like:
var that = this;
function registerUser(data) {
ajaxCall(pathServiceRegister, "POST", undefined, JSON.stringify(data), function (result) {
// SOME CODE THAT RUNS WHEN IT'S COMPLETE
// External method:
that.showAjaxLoader(false);
});
});
Declare your method like this
var obj = {
showAjaxLoader : function(show) {
var loader = $('.ajax-loader');
if (show) {
loader.fadeIn("fast");
} else {
loader.fadeOut("fast");
}
}
}
Then inside ajax, call obj.showAjaxLoader(false); This may work.

Dynamically send parameter in ajax-chosen

I am new to Jquery world.
I have these following codes:
$target.ajaxChosen({
type: 'GET',
url: '<s:url action="getFilterValueJSON" namespace="/cMIS/timetable"></s:url>?filterKey='+keyword,
dataType: 'json',
jsonTermKey: 'filterWord'
}, function (data) {
var terms = [];
mydata = data.valueMap;
$.each(mydata, function (i, val) {
terms.push({ value: i, text: val });
});
return terms;
});
It seems the variable 'keyword' does not dynamically changed its value. The value for 'keyword' comes from an element with on change event. Would someone enlighten me about this on how to solve this? Thanks in advance.
its better you compose your url object just before call
function onclick(keyword)
{
var url = '<s:url action="getFilterValueJSON" namespace="/cMIS/timetable"></s:url>?
filterKey='+keyword;
ajaxCall(url);
}
function ajaxCall(url)
{
$target.ajaxChosen({
type: 'GET',
url: url,
dataType: 'json',
jsonTermKey: 'filterWord'
}, function (data) {
var terms = [];
mydata = data.valueMap;
$.each(mydata, function (i, val) {
terms.push({ value: i, text: val });
});
return terms;
});
}

Execute callback function inside javascript object

I want to execute a callback function inside an object. I don't know if there is something wrong in the way I'm doing this.
I've googled for a solution, also searched on stackoverflow but couldn't find anything similar to the way I'm coding this.
PHPGateway.js
var PHPGateway = {
opt_friendlyURL: true,
opt_folder: 'ajax/',
callback_function: null,
useFriendlyURL: function (bool) {
this.opt_friendlyURL = bool;
},
setFolder: function (folder) {
this.opt_folder = folder;
},
send: function (service, method, data, callback) {
var url,
json_data = {};
if (this.opt_friendlyURL) {
url = this.opt_folder + service + '/' + method;
} else {
url = this.opt_folder + 'gateway.php?c=' + service + '&m=' + method;
}
if (data != undefined) {
json_data = JSON.stringify(data);
}
this.callback_function = (callback == undefined) ? null : callback;
$.ajax({
method: 'POST',
url: url,
data: {data: json_data},
success: this.ajax_success,
error: this.ajax_error
});
},
ajax_success: function (returned_object) {
if (this.callback_function != null) {
this.callback_function(returned_object.error, returned_object.data);
}
},
ajax_error: function () {
this.callback_function.call(false, {});
}
};
Then inside the HTML file that loads PHPGateway.js, I've the following code:
<script>
function submit_handler(event) {
event.preventDefault();
form_submit();
}
function form_callback(error, data) {
if(error == null) {
alert(data.text);
}
}
function form_submit() {
var data = {
status: $('#inStatus').val(),
amount: $('#inAmount').val(),
id: $('#inBudgetID'). val()
}
PHPGateway.send('budget', 'status', data, form_callback);
}
$('form').one('submit', submit_handler);
</script>
I get an error on this.callback_function(returned_object.error, returned_object.data);, the error is Uncaught TypeError: Object # has no method 'callback_function'.
What am I doing wrong?
Is this the best way to do it?
Thank You!
Based on minitech answer, I've updated PHPGateway.js like this. I've omitted the parts that weren't updated.
var PHPGateway = {
// Omitted code
send: function (service, method, data, callback) {
var url,
json_data = {},
that = this;
if (this.opt_friendlyURL) {
url = this.opt_folder + service + '/' + method;
} else {
url = this.opt_folder + 'gateway.php?c=' + service + '&m=' + method;
}
if (data != undefined) {
json_data = JSON.stringify(data);
}
this.callback_function = (callback == undefined) ? null : callback;
$.ajax({
method: 'POST',
url: url,
data: {data: json_data},
success: function(data, textStatus, jqXHR) {
that.ajax_success(data, textStatus, jqXHR);
},
error: function(jqXHR, textStatus, errorThrown) {
that.ajax_error(jqXHR, textStatus, errorThrown);
}
});
},
ajax_success: function (data, textStatus, jqXHR) {
if (this.callback_function != null) {
this.callback_function(true, data.data);
}
},
ajax_error: function (jqXHR, textStatus, errorThrown) {
this.callback_function.call(false, {});
}
};
Now it works!!!
In your call to $.ajax, you need to add a context option:
$.ajax({
method: 'POST',
url: url,
data: {data: json_data},
context: this,
success: this.ajax_success,
error: this.ajax_error
});
Your this variable in your Ajax success and error handlers are not pointing to the object you think they are. The context option to $.ajax() sets which object this points to in the Ajax callbacks.
Here’s your problem:
$.ajax({
method: 'POST',
url: url,
data: {data: json_data},
success: this.ajax_success,
error: this.ajax_error
});
When you set success and error to methods on this, they don’t keep their this. When a JavaScript function is called, it gets bound a this:
someFunction(); // this is undefined or the global object, depending on strict
someObject.someFunction(); // this is someObject
The built-in .call, .apply, and .bind of Function objects help you override this.
In your case, I think jQuery binds this to the Ajax object – a good reason to both not use jQuery and always use strict mode.
If you can guarantee or shim ES5 support, bind is an easy fix:
$.ajax({
method: 'POST',
url: url,
data: {data: json_data},
success: this.ajax_success.bind(this),
error: this.ajax_error.bind(this)
});
Which is equivalent to this if you can’t:
var that = this;
$.ajax({
method: 'POST',
url: url,
data: {data: json_data},
success: function() {
that.ajax_success.apply(that, arguments);
},
error: function() {
that.ajax_error.apply(that, arguments);
}
});
And now, a tip for you: don’t namespace, and if you do, don’t use this. this is great for objects that are meant to be constructed. What would seem more appropriate is something like this, if you really have to:
var PHPGateway = (function() {
var callbackFunction;
var options = {
friendlyURL: true,
…
};
…
function send(service, method, data, callback) {
…
}
…
return { send: send };
})();

Categories

Resources