So I've got a website where I want to click a button, check to see if the user has certain permissions, and if so popup a window to a new web page. On the java script I've got something like this:
function sendAjax(methodName, dataArray, success, error, category) {
var error2 = error || function () { };
$.ajax({
type: 'POST',
url: '/PermissionChecker' + methodName,
data: JSON.stringify(dataArray),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (r, s, x) { if (!success || success(r, s, x) != false) if (typeof (window.ChangeLogAdd) == 'function') { ChangeLogAdd(category); } },
error: error2
});
}
function CheckPermissions() {
sendAjax("CheckPermission", null, function (data) { var permission = eval('(' + data + ')'); if (permission == true) { alert('yay'); } else { alert('nay'); } }, null, 'Check Permission');
}
And the C# side is a simple function that does an if check and returns a bool. The function call goes through fine, but when it returns the bool I get a javascript error "Expected ']'". I assume this has something to do with my success function:
function (data) {
var permission = eval('(' + data + ')');
if (permission == true) {
alert('yay');
}
else {
alert('nay');
}
}
seeing as I didn't get this error before I tried what I'm doing there, so I was wondering how I would go about getting the data back from the ajax call to make pass the permission == true if/else check
Don't use eval for this purpose. It's unsafe and the source of many bugs. Just make the server respond with JSON and use $.getJSON.
Related
Here is my AJAX code:
jQuery.ajax({url: url,
method: 'GET',
data: getParams,
/*success: function (json, textStatus, jqXHR) {
if(jQuery.active <= 1){
waitDialog.removeWaitDialog();
}
createProcessButtonEvent();
ajaxError = false;
returnFunction(jqXHR.responseJSON);
},*/
complete: function(jqXHR, textStatus, errorThrown) {
if(jQuery.active <= 1){
waitDialog.removeWaitDialog();
}
createProcessButtonEvent();
var response;
if (typeof jqXHR.responseJSON === 'object') {
response = jqXHR.responseJSON;
} else {
response = jqXHR.responseText;
}
if(response.errors.length == 1){ // jsonResults.message != ''
if(!warningMessage){ //hard coded for ad designer
jQuery('#alertMessageText').text(response.errors[0].message);
jQuery('#alertMessage').show();
jQuery('#waitDialog').jqmHide();
ajaxError = true;
return;
}
warningMessage.displayMessage(response.errors[0].message);
jQuery('.popup').modal('hide');
jQuery('.popup').not('.persist').remove();
}
if (response.errors.length > 1){
for(var n = 0; n < response.errors.length; n++){
if (response.errors[n].id == 1){ // 2005
window.location.href = '/login?destination=' + encodeURIComponent(window.location.pathname + window.location.search);
}
if (response.errors[n].id == 9500){
statusMessage.displayMessage(response.errors[n].message);
}
}
ajaxError = true;
//if(errorFunction){
// errorFunction(jsonResults);
//}
waitDialog.removeWaitDialog();
}
if (!ajaxError) {
returnFunction(jqXHR.responseJSON);
}
},
dataType: 'json',
contentType: 'application/json'
});
I tell it to go to http://127.0.0.1/api/parameter, where the parameter is an invalid resource. My API returns in a new tab:
{"errors":[{"id":3,"message":"GET route not defined for /api/parameter"}],data:{}}
I have it returning with a 500 status code because accessing an invalid resource is an error. When I call the actual AJAX, I get jqXHR.responseJSON is null, and jqXHR.responseText is ''.
I have tried using both success: and error: blocks, and tried the complete: because it seemed like my API was resolving the call after the error block had been called, as you can see with the comments.
So I get TypeError: response is null, because my response object is never populated, and the strangest thing is that my call to parameter?parameters=here is never available to inspect in the Network
Since I have control over the API, I changed this specific error to return with status code 501 Not Implemented, instead of 500, and it seems to work. It looks like this was a very unique edge case.
I'm trying to generate html content based on the presence of a specific key in the local storage. The code is as follows:
// Check if the user is signed in or not
if(localStorage.getItem("token") === null) {
document.getElementById("main").innerHTML = document.getElementById("welcomeview").innerHTML;
} else {
document.getElementById("main").innerHTML = document.getElementById("profileview").innerHTML;
}
The profile view is always shown even though there is no token key set in the local storage:
localStorage
Storage { token: "undefined", length: 1 }
Why?
Edit:
The token is being set with the response value of an AJAX request:
function sign_in() {
var uri, method, formId, $form, form_data;
uri = location.protocol + '//' + location.host + "/sign_in";
method = "POST";
formId = "#signin_form_id";
$form = $(formId);
form_data = get_form_data($form);
// Set-up ajax call
var request = {
url: uri,
type: method,
contentType: "application/json",
accepts: "application/json",
cache: false,
dataType: 'json',
data: form_data
};
// Make the request
$.ajax(request).done(function(data) { // Handle the response
// Attributes are retrieved as object.attribute_name
// alert(obj.count);
if(data.successSignIn === false) {
// Login failed we show the welcome page
alert(data.message);
document.getElementById("main").innerHTML = document.getElementById("welcomeview").innerHTML;
} else {
// Login succeeded. We load the user's info, his messages and also a form in which he can type messages
// Save the token received from the server. Could also be stored as a cookie
localStorage.setItem('token', data.token);
// Go to the home page
go_home();
}
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
);
location.reload();
}
Edited: Try this for set item localStorage.setItem("token", typeof undefined === data.token ? undefined : data.token). It is avoided to be string "undefined".
I suggest that:
1) Replace to if(localStorage.getItem("token")) {...}
3) Also, you can do your example through ternary operator
var welcomeText = document.getElementById("welcomeview").innerHTML,
profileText = document.getElementById("profileview").innerHTML;
document.getElementById("main").innerHTML = (localStorage.getItem("token")) ? welcomeText : profileText
You'd never enter the if section as "undefined" === null is always false.
You'd want to check for if(localStorage.getItem("token") === "undefined") in your case.
I have a weired bug that is driving me crazy for some time now. I have the following piece of code:
function isLoggedIn() {
var loggedIn = false;
var requestData = {
action: 'explore-webdesign-is-loggedin',
request_url: location.protocol + '//' + location.host + location.pathname,
async: false,
data: null
};
jQuery.post(ajaxurl, requestData, function(data) {
var dataObj = JSON.parse(data);
if (dataObj.success === true) {
loggedIn = true;
alert("1.) " + loggedIn);
}
});
alert("2.) " + loggedIn);
return loggedIn;
};
Javascript spitts out both alerts, which is fine, however the first one says '1.) true' while the second one gives me '2.) false'. What is going on?
AJAX requests are asynchronous - your final alert is being executed while the AJAX is in progress - the first alert finishes once the AJAX is done (hence why it's in the callback).
You don't return from an async method like you are trying to do, instead you would pass a callback function in to be executed once the AJAX is done:
function isLoggedIn(callback) {
...
...
jQuery.post(ajaxurl, requestData, function(data) {
...
...
if (dataObj.success === true) {
loggedIn = true;
callback(loggedIn);
}
});
}
Then call like so:
isLoggedIn(function(data) {
if (data) //user is logged in
});
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Return Value from inside of $.ajax() function
I'm working on a CakePHP app that makes use of widespread AJAX calls to controllers. I'm stuck with one particular AJAX call in which I'm trying to assign the response from the controller to a JS global variable. Here is the code:
window.errors = "";
function setErrors(err) {
window.errors = err;
}
function ajaxCall(u, t, d, dt) {
var type = typeof t !== 'undefined' ? t : "post";
var dataType = typeof dt !== 'undefined' ? dt : "json";
var success = false;
var err = "";
$.ajax({url: url, data: "data=" + d, type: type, dataType: dataType,
success: function(d){
if(d.hasOwnProperty('success') === false) { //json response
for(var i in d) { //fetch validation errors from object
for(var j in i) {
if(typeof d[i][j] === "undefined") {
continue;
}
err += d[i][j] + "<br/>";
}
}
console.log(err); //<=== displays correct value
setErrors(err); //<=== but somehow this seems to be failing??
}
else {
if(d.success === "1") {
success = true;
}
}
}
});
return success; //<=== I suspect this might be the culprit
}
And this is how ajaxCall() is used:
function register() {
var data = {};
var $inputs = $("#regForm :input");
$inputs.each(function(){
data[this.name] = $(this).val();
});
data = {"User" : data }; //CakePHP compatible object
data = JSON.stringify(data);
//Here's the AJAX call
if(ajaxCall('https://localhost/users/add', 'post', data, 'json')) {
alert("Registered!");
}
else {
alert(window.errors); // <=== empty string
console.log("window.errors is: " + window.errors); // <=== empty string
}
}
But on the Chrome JS console, window.errors returns the correct value (non-empty, validation error string).
I found a similar question that possibly might be addressing my issue (the return success immediately following the $.ajax() is being executed before the success: callback). How can I fix this without drastically changing the code (also, I don't want to make this a synchronous call)?
Yes, you are right that the return statement runs before the success callback. You can't return the result from the function, as the function has to return before the success event can be handled.
Add a callback to the ajaxCall function, and call that instead of setting the success variable:
function ajaxCall(u, t, d, dt, callback) {
var type = typeof t !== 'undefined' ? t : "post";
var dataType = typeof dt !== 'undefined' ? dt : "json";
$.ajax({url: url, data: "data=" + d, type: type, dataType: dataType,
success: function(d){
if(d.hasOwnProperty('success') === false) { //json response
for(var i in d) { //fetch validation errors from object
for(var j in i) {
if(typeof d[i][j] === "undefined") {
continue;
}
err += d[i][j] + "<br/>";
}
}
callback(false, err);
} else {
callback(d.success === "1", "");
}
}
});
}
Send the code for handling the result into the ajaxCall function:
ajaxCall('https://localhost/users/add', 'post', data, 'json', function(success, err){
if (success) {
alert("Registered!");
} else {
alert(err);
}
});
I have problems transferring a dataset (array of objects) from a servlet to a jsp/jquery.
This is the dataset sent by the servlet (Json):
[
{aktion:"ac1", id:"26"},
{aktion:"ac2", id:"1"},
{aktion:"ac3", id:"16"},
{aktion:"ac4", id:"2"}
]
The jsp:
function getSelectContent($selectID) {
alert('test');
$.ajax({
url:'ShowOverviewDOC',
type:'GET',
data: 'q=getAktionenAsDropdown',
dataType: 'json',
error: function() {
alert('Error loading json data!');
},
success: function(json){
var output = '';
for (p in json) {
$('#'+$selectID).append($('<option>').text(json[p].aktion).attr('value', json[p].aktion));
}
}});
};
If I try to run this the Error ('Error loading json data') is alerted.
Has someone an idea where the mistake may be?
Thanks!
If the error function is running, then your server is returning an error response (HTTP response code >= 400).
To see exactly what is going on, check the textStatus and errorThrown information that is provided by the error callback. That might help narrow it down.
http://api.jquery.com/jQuery.ajax/
The way you are setting the data parameter looks a bit suspect (notice JSON encoding in my example below). Here is how it would look calling a .Net asmx
$.ajax({
url: "/_layouts/DashboardService.asmx/MinimizeWidgetState",
data: "{'widgetType':'" + widgetType + "', 'isMinimized':'" + collapsed + "'}"
});
Also the return data is by default placed in the .d property of the return variable. You can change this default behavior by adding some ajax setup script.
//Global AJAX Setup, sets default properties for ajax calls. Allows browsers to make use of native JSON parsing (if present)
//and resolves issues with certain ASP.NET AJAX services pulling data from the ".d" attribute.
$.ajaxSetup({
type: "POST",
contentType: "application/json; charset=utf-8",
data: "{}",
success: function(msg) {
if (this.console && typeof console.log != "undefined")
console.log(msg);
},
dataFilter: function(data) {
var msg;
//If there's native JSON parsing then use it.
if (typeof (JSON) !== 'undefined' && typeof (JSON.parse) === 'function')
msg = JSON.parse(data);
else
msg = eval('(' + data + ')');
//If the data is stuck in the "."d" property then go find it.
if (msg.hasOwnProperty('d'))
return msg.d;
else
return msg;
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
handleAjaxError(XMLHttpRequest, textStatus, errorThrown);
}
});