I'm making multiple REST calls via Javascript to determine if a user is in several Sharepoint groups.
If the user is not in the group, the REST request returns a status of 500, along with a message saying "user cannot be found".
When an error is returned, I resolve my promise with "false", so my function works ok.
But - every REST response of 500 puts an error entry in the Javascript console - is it possible to suppress those entries?
I know they don't impact the function, but it clutters up the console.
function IsUserInGroupNumber(permissionRequested,userEmail,groupNumber){
var deferred=$.Deferred();
var url=L_Menu_BaseUrl+"/_api/web/sitegroups("+groupNumber+")/Users/getByEmail('"+userEmail+"')/Email";
$.ajax({
type: 'GET',
url: url,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json; odata=verbose");
},
processData: false,
success: function (data)
{
deferred.resolve({requestedPermission:permissionRequested,groupNumber:groupNumber,hasPermission:true});
},
error: function(data){
//user not found in the group returns a 500 error - but return value of 'false'
deferred.resolve({requestedPermission:permissionRequested,groupNumber:groupNumber,hasPermission:false});
}
});
return deferred.promise();
}
The service shouldn't respond with a 500 status code. That means something on the server is failing. You can't control how the JavaScript console / browser interprets and resolves an error or status.
Also, as of jQuery 1.5, $.ajax already returns a promise: http://api.jquery.com/jquery.ajax/
You could simplify your code a great deal with something like:
function IsUserInGroupNumber(permissionRequested, userEmail, groupNumber){
return new Promise(resolve, reject) {
$.ajax({
type: 'GET',
url: L_Menu_BaseUrl + "/_api/web/sitegroups(" + groupNumber + ")/Users/getByEmail('" + email + "')/Email",
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json; odata=verbose");
},
processData: false,
})
.done(function() {
resolve(true)
})
.fail(function() {
resolve(false)
})
}
Related
I'm trying to access an item in an api so I can start getting data from the json file, but I can't seem to get anything to work. I'm unable to log any of the data I'm trying to access to the console.
$(function() {
$.ajax({
type: 'GET',
url: "xxx",
dataType: 'json',
success: function(data) {
return console.log('success', data);
return console.log(data[0].id);
},
beforeSend: function(xhr, settings) {
xhr.setRequestHeader('Authorization', 'Bearer ' + 'xxx');
}
});
});
It isn't working because you are returning before the second console.log. the return statement is used to exit a function at that line and return the value of the rest of the line. You are returning then trying to do something after the return which actually is never ran.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return
Remove the return statements and it should work.
$.ajax({
type: 'GET',
url: "xxx",
dataType: 'json',
success: function(data) {
console.log('success', data);
console.log(data[0].id);
},
beforeSend: function(xhr, settings) {
xhr.setRequestHeader('Authorization', 'Bearer ' + 'xxx');
}
});
1) You have a problem with returning before the Id is logged to the console, as you are returning it before your you logging your Id, a return statement ends the function execution. so removing the return will do the work
2) you don't really need to console.log() everything you can just put a 'debugger;' instead of return and you can reload the page with an open console window, it will pause the code execution at the debugger; and you can hover on the 'data' being received in the success function to see all the data being received on a successful AJAX call. hope this helps
I'm making an ajax post request with success, failure and status code handlers. However, when the request fails with a 400 error, part of the success function is still called. Could someone please tell me why?
$.ajax({
type: "POST",
url: saveToGetTalentUrl.url,
data: JSON.stringify(candidateList),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
$("#save_to_getTalent").replaceWith("Saved to getTalent");
alert("New User " + response.candidate.full_name + " created successfully");
console.log(msg);
//normalExec(response, msg);
},
error: function (errormessage) {
console.log(errormessage);
},
statusCode: {
400:function(){
alert(errors.err400);
},
401:function(){
alert(errors.err401);
},
403:function(){
alert(errors.err403);
},
500:function(){
alert(errors.err500);
}
}
});
}
When the call fails with a 400 error, the error from statusCode is displayed and the error is logged from the error function, but at the same time, the line $("#save_to_getTalent").replaceWith("Saved to getTalent"); is also called. I dont understand why
Try set async: true to see what happens.
See this part in the jQuery documentation for ajax:
async (default: true)
Type: Boolean
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done().
So, the request by default (async: true) are sent one by one, not all together. If the POST takes a while, you may see the callback function executed before the POST request returned completely. When the first line of success is executed, it is blocked because you have a dialog popped up; meanwhile, the statusCode part is also executed; it continues to the end because nothing is blocking there.
Debug with a dialog is not the best solution because it always blocks; you can try to change some element's value to see the execute order, like changing an <input>'s value, append a number to see if the whole number string changes or not, to see if there is a race condition of success and statusCode.
Something like:
$.ajax({
data:
url:
success: function(returned, status, xhr) {
$('#testInput').val($('#testInput').val() + "1");
},
error: function (errormessage) {
$('#testInput').val($('#testInput').val() + "2");
},
statusCode: {
400:function(){
$('#testInput').val($('#testInput').val() + "3");
},
401:function(){
$('#testInput').val($('#testInput').val() + "4");
},
403:function(){
$('#testInput').val($('#testInput').val() + "5");
},
500:function(){
$('#testInput').val($('#testInput').val() + "6");
}
}
});
I am writing a Javascript API client using jQuery. My top level request method looks like this:
function request(method, uri, params, proxies) {
var deferred = $.Deferred();
$.ajax({
data: method == 'GET' ? params : JSON.stringify(params),
contentType: 'application/json',
dataType: 'json',
url: api.root + uri,
type: method,
xhrFields: {
withCredentials: true
}
}).done(function(body) {
deferred.resolveWith(this, [body.data]);
}).fail(function(xhr) {
deferred.rejectWith(this, [xhr]);
});
return deferred.promise();
},
How can I have a default fail handler for my returned deferred? That is, if the deferred has no other handlers attached to it's fail condition, call a default handler.
I want to do this to have global exception handling in my application, except for the parts that have a specific handling (and will define their own fail handler on the deferred).
So, the cleanest way to use jQuery ajax in an API as of 2016 is to return a promise. But, you cannot determine whether a caller has attached an error handler or not to the promise.
So, what I'd suggest is that you just add a new argument to your function that tells the function to NOT apply the default error handling because the caller will take care of the error handling. And, I'd suggest you avoid the promise anti-pattern by just using the existing promise $.ajax() already returns rather than creating your own deferred:
function request(method, uri, params, proxies, skipDefaultErrorHandling){
// default error handling will be used if nothing is passed
// for skipDefaultErrorHandling
var p = $.ajax({
data: method=='GET'?params:JSON.stringify(params),
contentType: 'application/json',
dataType: 'json',
url: api.root + uri,
type: method,
xhrFields: {
withCredentials: true
}
});
if (!skipDefaultErrorHandling) {
// apply default error handling
p = p.then(null, function(jqXHR, textStatus, errorThrown) {
// put here whatever you want the default error handling to be
// then return the rejection with the various error parameters available
return $.Deferred().reject([jqXHR, textStatus, errorThrown]);
});
}
return p;
};
Then, the caller just decides whether to apply their own error handling or not:
request(...).then(function(data) {
// success code here
});
Or, you can go with a non-promise failHandler callback that you pass in and your default error handling looks to see if that failHandler was passed in or not. This is hybrid of promises and callbacks and is not something I would normally choose to architect, but since your question asks for something that promises do not support, this is one of achieving that:
function request(method, uri, params, proxies, failHandler){
// default error handling will be used if nothing is passed
// for skipDefaultErrorHandling
var p = $.ajax({
data: method=='GET'?params:JSON.stringify(params),
contentType: 'application/json',
dataType: 'json',
url: api.root + uri,
type: method,
xhrFields: {
withCredentials: true
}
});
// apply default error handling
p = p.then(null, function(jqXHR, textStatus, errorThrown) {
if (failHandler) {
// call passed in error handling
failHandler.apply(this, arguments);
} else {
// do your default error handling here
}
// then keep the promise rejected so the caller doesn't think it
// succeeded when it actually failed
return $.Deferred().reject([jqXHR, textStatus, errorThrown]);
});
return p;
};
After reading various examples on stackoverflow I wrote this function :
function showGetResult(crossDomainUrl) {
$.ajax({
url: crossDomainUrl,
type : 'GET',
crossDomain: true,
success: function (data) {
debug(data);
return data;
}
});
}
and called it using this
alert(showGetResult(crossDomainUrl));
But all I get is 'undefined', this is being used in a web-browser extension inside a content-script.
This is because the Ajax request runs asynchronously. The return data doesn't do anything. You could change it to (updated to reflect the request in the comments to be able to download a script):
function showGetResult(crossDomainUrl) {
return $.ajax({
url: crossDomainUrl,
type : 'GET',
dataType: 'script',
crossDomain: true
});
}
showGetResult('http://code.jquery.com/ui/1.10.3/jquery-ui.js')
.done(function(data) {
alert("success: " + data);
})
.fail(function(jqXHR, textStatus, ex) {
alert("failed: " + textStatus);
});
For the call actually to work cross-domain, you will need to use jsonp or script. Read this wiki for more information about Same-origin policy. Refer to this answer for more information about using jsonp.
The code above will inject the downloaded jscript in the dom and execute it.
The $.ajax() set up the query, and return immediately, so the function returns before the request is completed. Specify a function to call on completion of the query using success.
function showGetResult(crossDomainUrl) {
$.ajax({
url: crossDomainUrl,
type : 'GET',
crossDomain: true,
success: showData
});
}
function showData(data){
debug(data);
return data;
}
showGetResult(crossDomainUrl);
see http://jsfiddle.net/5J66u/8/ - (updated to specify jsonp and a better URL for it)
Let's say for example, I have the following javascript function that returns a boolean:
function CallWebServiceToUpdateSessionUser(target, user)
{
var dataText = { "jsonUser": JSON.stringify(user) };
$.ajax({
type: "POST",
url: target,
data: JSON.stringify(dataText),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response)
{
return true;
},
failure: function (msg)
{
return false;
}
});
}
and the target function on the server that is being called could take up to... 15 seconds to respond.
How do I guarantee that this function will not exit until after the server call has been completed? Or, how can I guarantee that who ever is calling this function will get a true/false and not an undefined?
NOTE:
I've seen people use async: false but that hangs the UI which I do not want.
See http://api.jquery.com/jQuery.ajax/. You need to do an AJAX request with async: true to your parameters. You will then need to edit your code so the code that executes after a successful request is inside the successful block.