Ajax attached to click event not getting spied using sinon - javascript

I have some js for which I want to write unit test cases using sinon. My js looks like following
var succesHandler = function() {
console.log("yeah success");
};
var failureHandler = function() {
console.log("oops error");
};
var ajaxCall = function(payload, successHandler, failureHandler) {
$.ajax({
type: "POST",
url: "/myUrl",
contentType: 'application/json',
data: JSON.stringify(payload),
success: successHandler,
error: failureHandler
});
};
$('#my-button').live('click', function() {
var dummyPayload = {
"hello" : "coder"
};
ajaxCall(dummyPayload, successHandler, failureHandler);
});
return {
ajaxCall: ajaxCall,
successHandler: successHandler,
failureHandler: failureHandler
};
I want to know how do I spy the ajaxCall() method attached to the #my-button click? Also, how to spy successHandler and failureHandler

Related

Vuejs method ajax call other method on component

how to call another method inside jquery ajax?
methods : {
calert(type,msg="",error=""){
console.log("call me");
},
getData(){
$.ajax({
type: "GET",
success: function(data){
// error calert not found
calert(true,"","asd");
},
error: function (error) {
// also error calert not found
this.calert(false,"",error);
},
complete: function(){
},
url: "/test",
});
},
}
i have try to using this.calert but it doesn't work, still error
You simply need to update your code to use arrow functions, as follows:
methods : {
calert(type,msg="",error=""){
console.log("call me");
},
getData(){
$.ajax({
type: "GET",
success: (data) => {
this.calert(true,"","asd");
},
error: (error) => {
this.calert(false,"",error);
},
complete: (){
},
url: "/test",
});
},
}
Or alternatively, store a local reference to the method, like:
methods : {
calert(type,msg="",error=""){
console.log("call me");
},
getData(){
const { calert } = this;
$.ajax({
type: "GET",
success: function(data){
// error calert not found
calert(true,"","asd");
},
error: function (error) {
// also error calert not found
calert(false,"",error);
},
complete: function(){
},
url: "/test",
});
},
}
btw i found the solution, looks like little bit tricky using this
methods : {
calert(type,msg="",error=""){
console.log("call me");
},
getData(){
let vm = this;
$.ajax({
type: "GET",
success: function(data){
// error calert not found
vm.calert(true,"","asd");
},
error: function (error) {
// also error calert not found
vm.calert(false,"",error);
},
complete: function(){
},
url: "/test",
});
},
}
i store the this to variable and then i use the variable to call another methods.
Anyone have any solutions better than this?
Thanks

wait ajax finish in a function

I have an object with function foo containing a jQuery ajax call
foo: function() {
...
jQuery.ajax({
contentType : "application/json",
type: "POST",
async: true,
...,
success: function(data) {
globalVariable = 1;
},
error: function(error) {
}
});
}
My test code:
var pass = true;
myObj.foo();
if (globalVariable !== 1) {
pass = false;
}
I want statement myObj.foo() finish with ajax finish too. If ajax does not finish, the globalVariable is not equal to 1.
I cannot set async to false in ajax because that is production code.
Your function is running. It's just that it's running asychrounously. If you want to halt your other processes while foo() runs, set async to false.
foo: function() {
...
jQuery.ajax({
contentType : "application/json",
type: "POST",
async: false,
...,
success: function(data) {
globalVariable = 1;
},
error: function(error) {
}
});
}
If that's the case add a function parameter to foo instead. That function will be called after the ajax call has finished.
var bar = function(){
pass=true;
}
Then foo will become
foo: function(func) {
...
jQuery.ajax({
contentType : "application/json",
type: "POST",
async: false,
...,
success: function(data) {
globalVariable = 1;
func();
},
error: function(error) {
}
});
}
Call foo
var pass = false;
myObj.foo(bar);
A code snippet follows promise approach:
var pass = true;
var myObj = {
foo: function () {
return $.Deferred(function (deferred) {
jQuery.ajax({
type: "POST",
url: 'https://httpbin.org/post'
}).done(function () {
deferred.resolve(1);
}).fail(function () {
deferred.reject();
});
}).promise();
}
};
myObj.foo().done(function (globalVariable) {
if (globalVariable !== 1) {
pass = false;
}
});

Ajax Call not calling the Controller Action Method

I'm not able to make ajax call to the controller action method which returns the json object.
Also, I want to pass the integer-CheckID to the method.
Any help is highly appreciated.
Thanks in Advance!
***View***
<script type="text/javascript">
function showCheckImage(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
var CheckID = dataItem.ID;
$.ajax({
url: '#Url.Action("GetDeferredCheckImage", "Customer")',
type: 'POST',
data: {deferredCheckID: CheckID },
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function(result) {
//var imageObj = result;
alert('Loaded Image Object!');
},
error: function (result) {
alert('Error occurred while loading the image object.');
}
});
}
**Controller Method**
[HttpPost]
public JsonResult GetDeferredCheckImage(int deferredCheckID)
{
try
{
QCEventLogger.Log($"Gathering deferred check image for check ID: {deferredCheckID}", LogType.Default);
var response = new AjaxGetDeferredCheckImageViewModel(deferredCheckID);
QCEventLogger.Log($"Result of service call to gather deferred check image. check ID: {deferredCheckID}. Success: {response.Success}", LogType.Default);
var DeferredCheckImageObject = response.ImageCheckObject.DeferredCheckImages.FirstOrDefault();
return Json(DeferredCheckImageObject, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
var failureResponse = new AjaxGetDeferredCheckImageViewModel() { Success = false };
QCErrorLogger.Log($"Failure trying to gather deferred check image for check ID: {deferredCheckID}", ex);
return Json(failureResponse, JsonRequestBehavior.AllowGet);
}
}
Your ajax call might be like this,
$.ajax({
url: '#Url.Action("GetDeferredCheckImage", "Customer")',
type: 'POST',
data: { deferredCheckID: CheckID },
dataType: 'json',
success: function (result) {
//var imageObj = result;
alert('Loaded Image Object!');
},
error: function (result) {
alert('Error occurred while loading the image object.');
}
});

show() overwritten multiple ajax calls

I have one html element (elem1) and 2 JS functions (func1, func2) that hides and shows elem1 respectively. These JS functions make individual ajax calls and func2 is calling func1 internally.
Problem: I need to call func2, which internally calls func1. Calling func1 hides elem1. After calling func1, I want to show elem1. But this show is not working.
JSFiddle: https://jsfiddle.net/46o93od2/21/
HTML:
<div id="elem">
Save ME
</div>
<br/>
<button onclick="func1()" id="func1">Try Func1</button>
<button onclick="func2()" id="func2">Try Func2</button>
JS:
function func1() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {}, // send in your data
success: function (data) {
//var aData = JSON.parse(data); // there is no data to parse
$('#elem').hide();
},
error: function (xhr, errmsg, err) {
alert('error');
}
});
}
function func2() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {}, // send in your data
success: function (data) {
//var aData = JSON.parse(data); // there is no data to parse
func1();
$('#elem').show();
},
error: function (xhr, errmsg, err) {
alert('error');
}
});
}
Make func1 take a callback function that tells it what to do after it gets the response. func2 can pass a function that shows the element.
function func1(callback) {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {
json: ''
}, // send in your data
success: function(data) {
if (callback) {
callback();
} else {
$('#elem').hide();
}
},
error: function(xhr, errmsg, err) {
alert('error');
}
});
}
function func2() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {
json: ''
}, // send in your data
success: function(data) {
func1(function() {
$('#elem').show();
});
},
error: function(xhr, errmsg, err) {
alert('error');
}
});
}
DEMO

make another Jquery AJAX call in error case of existing AJAX call

I have the following code which work fine in case of success and error. But what I want to do is make another ajax call in case of error. to some other URL . what is the correct way of doing it. I tried calling the ajax function again but it resulted in a javascript error
this is the sample of working code.
$('#save-walkin').die('vclick').live('vclick', function(e) {
e.preventDefault();
$.mobile.showPageLoadingMsg();
$.ajax({
url: 'http://www.someurl.com',
method: 'POST',
data: $('#form-createwalkin').serialize(),
success: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
},
error: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
}
});
return false;
});
Where as what I am trying to do is something like this. but It's not working
$('#save-walkin').die('vclick').live('vclick', function(e) {
e.preventDefault();
$.mobile.showPageLoadingMsg();
$.ajax({
url: 'http://www.someurl.com',
method: 'POST',
data: $('#form-createwalkin').serialize(),
success: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
},
error: function(){
$.ajax({
url: 'http://www.someotherurl.com',
method: 'POST',
data: $('#form-createwalkin').serialize(),
success: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
},
error: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
}
}
});
return false;
});
It's just not formed correctly. It should look like this:
$('#save-walkin').die('vclick').live('vclick', function(e) {
e.preventDefault();
$.mobile.showPageLoadingMsg();
$.ajax({
url: 'http://www.someurl.com',
method: 'POST',
data: $('#form-createwalkin').serialize(),
success: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
},
error: function(){
$.ajax({
url: 'http://www.someotherurl.com',
method: 'POST',
data: $('#form-createwalkin').serialize(),
success: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
},
error: function(){
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
}
});
}
});
return false;
});
Use Deferred objects, those are objects to manipulate async calls, you can solve :
$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
.then(myFunc, myFailure);
This way myFunc executes after the 2 ajax calls are made, and myFailure if either one has an error.
You can read more about it in the jquery official documentation:JQuery Deferred Object
Something like this, storing the Ajax in an object gives you a lot more flexibility, and in the error (fail) function, just call the function again with a different URL.
Will probably need some adjusting, and a counter if it's only suppose to repeat once!
runAjax('http://www.someurl.com');
funcion runAjax(url) {
var jqXHR = $.ajax({
url: url,
method: 'POST',
data: $('#form-createwalkin').serialize()
});
}
jqXHR.done(function() {
$.mobile.hidePageLoadingMsg ();
document.location.href = "queue.php";
}.fail(function() {
runAjax('http://www.someotherurl.com');
});
I think first you have to check your callback,, or error what you are getting..
may be it will help you..
$.ajax({
statusCode: {
404: function() {
alert('page not found');
}
}
});
you can also try to give
var menuId = $("ul.nav").first().attr("id");
var request = $.ajax({
url: "script.php",
type: "POST",
data: {id : menuId},
dataType: "html"
});
request.done(function(msg) {
$("#log").html( msg );
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});

Categories