Solved

Why is Ajax Success or Failure not being called

Posted on 2014-02-07
42
543 Views
Last Modified: 2014-02-14
I am still writing my first application in MVC and using jquery and Ajax and everytime I figure out something or somebody helps me with an issue in here, I come across something else.

I have a Ajax function which sends the ID of a record to an action which deletes the record and then on success it should reload the table using another function.
but it seemed to be not working until I refreshed the page and noticed the record missing.
When I did it again watching on Firebug and Debug mode in VS I noticed the function got called, then it called the action which completed but when it went back to the function it went to success but jumped over it, then went to failure and jumped over it

Here is the function
  function DeleteDeviation () {
        $.ajax({
                    url: "/Deviations/Delete/" + Recordid, 
                   type: "POST",                   
                   success: function(result) {
                        getRemarks();
                    },
                    failed: function(c) {
                        alert(c.text);
                    }
                });
       
       }

Open in new window

I can't understand why it is not seeing a success. I know I'm probably making a schoolboy mistake but any help would be greatly appreciated again
0
Comment
Question by:Niall292
  • 25
  • 10
  • 4
  • +1
42 Comments
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
Comment Utility
Is your  getRemarks(); reloading the page or doing a refresh?
0
 

Author Comment

by:Niall292
Comment Utility
It reloads the table again. This is it.
       function getRemarks() {
            $.ajax({
                type:"GET",
                url:"/Remarks/Index/" + TreeId,
                success: function(content) {
                    $("#content").empty();
                    $("#content").html(content);               
                } 
                              
            }); 
        }

Open in new window

I'm using the exact same idea when I enter new remarks and again call this function and it works perfectly
0
 
LVL 58

Assisted Solution

by:Gary
Gary earned 333 total points
Comment Utility
Normally for this situation you would just remove the HTML (table row) from the page, if you are reloading the page/code then you are negating the reason for using Ajax in the first place.
0
 

Author Comment

by:Niall292
Comment Utility
I thought you might have found something because it should have been calling getDeviations which looks like this:
     function getDeviations() {          
            $.ajax({
                type:"GET",
                url:"/Deviations/Index/" + TreeId,
                success: function(content) {
                    $("#content").empty();
                    $("#content").html(content);
               
                }               
            }); 
        }

Open in new window


but it never actually calls the function at all because that is in the Success and it just jumps over it

I made the change to the other function as well but no change in it's reaction
   function DeleteDeviation () {
        $.ajax({
                    url: "/Deviations/Delete/" + Recordid, 
                   type: "POST",                   
                   success: function(result) {
                        getDeviations();
                    },
                    failed: function(c) {
                        alert(c.text);
                    }
                });
       
       }

Open in new window

0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
Comment Utility
You should be able to update the content id like this
 function DeleteDeviation () {
        $.ajax({
                    url: "/Deviations/Delete/" + Recordid, 
                   type: "POST",                   
                   success: function(result) {
                       // getRemarks();
                        $("#content").html(result);
                    },
                    failed: function(c) {
                        alert(c.text);
                    }
                });
       
       }

Open in new window

0
 

Author Comment

by:Niall292
Comment Utility
I am not reloading the page. I am using partial views but if you think that is why it is not working I am willing to try anything
0
 

Author Comment

by:Niall292
Comment Utility
@Cathal,
Sorry it took me a few seconds to digest what you said.
How would I just remove the HTML row.

That sounds like it would a great idea
0
 
LVL 58

Assisted Solution

by:Gary
Gary earned 333 total points
Comment Utility
I would need to see your HTML and where you are getting the id from.
If you are clicking something in the row to remove it then you can just find the closest TR and remove it or if there is something like a data- attribute identifying the row by the ID then you can use that to remove it
0
 

Author Comment

by:Niall292
Comment Utility
but then again would you not do that on success which is the problem I came with.

Although I do like your idea (saving me round trips)
0
 
LVL 58

Expert Comment

by:Gary
Comment Utility
Yes it would be in the success callback
0
 

Author Comment

by:Niall292
Comment Utility
This is how I am calling the DeleteDeviations Function

<script type="text/javascript" >
    $(document).ready(function() {
        $('.delete-record').click(function() {
            $(this).closest("tr").css("background-color", "#00FFFF");
            Recordid = $(this).closest("tr").data("id");
            if (confirm("Are you sure you want to delete this record")) {
                DeleteDeviation();

            }
            $(this).closest("tr").css("background-color", "white")
        })

    });
</script>

Open in new window

0
 

Author Comment

by:Niall292
Comment Utility
@Scott,
Scott I only seen your response now and will try it but again I think it will not get called because of the issue with success
0
 
LVL 58

Expert Comment

by:Gary
Comment Utility
<script type="text/javascript" >
    $(document).ready(function() {
        $('.delete-record').click(function() {
            $(this).closest("tr").css("background-color", "#00FFFF");
            Recordid = $(this).closest("tr").data("id");
            if (confirm("Are you sure you want to delete this record")) {
                DeleteDeviation(Recordid );

            }
            $(this).closest("tr").css("background-color", "white")
        })

    });
</script> 

Open in new window


  function DeleteDeviation (recID) {
        $.ajax({
                    url: "/Deviations/Delete/" + Recordid, 
                   type: "POST",                   
                   success: function(result,recID) {
$("tr").data(recID).remove()
//                      getRemarks();
                    },
                    failed: function(c) {
                        alert(c.text);
                    }
                });
       
       } 

Open in new window

0
 

Author Comment

by:Niall292
Comment Utility
If it helps, I just looked at firebug and I am getting a 302 Found

and then 500 Internal Server Error
 The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'MvcRoster.Controllers.DeviationsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'MvcRoster.Controllers.DeviationsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters

Open in new window

but the ID is passed into the getDeviations
0
 

Author Comment

by:Niall292
Comment Utility
Can you guys help with what might be causing the 302 error or is there any more info I info I  give to help solve this
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
Comment Utility
Make sure there is data being passed as the ID.  

Also, is this just sample code?   I would include some type of hash sha or md5.  Not so much for security as I expect you have somebody logged in, but to make sure you are supposed to be deleting.  It would not be so good if the url was hit by mistake with or without the ajax call.

You can do a quick sha hash in either js https://code.google.com/p/crypto-js/ (don't use client side for anything that is really secret).  Or generate a hash on the serverside.   The url might be  /Deviations/Delete/" + Recordid&"/"&key where the key is a hash of at least the recordid and date.  Then on the other end you you are checking that the incoming hash equals the record id and current date (just the date, not time).   You could also include the the user or whatever else.  This would prevent somebody from simply hitting /Deviations/Delete/1233 and deleting something at random.
0
 

Author Comment

by:Niall292
Comment Utility
This is an intranet site where only certain users can open the website. So I am not really worried also the delete process doesn't really delete it, it marks it as deleted and then gets the windows logon of who deleted it and when.
Although it is all done on partial views the main URL never changes so they would never see Devialtions/Delete/****
0
 

Author Comment

by:Niall292
Comment Utility
@Scott.
If you look at the getDeviations function it passes  Deviations/Index/ +TreeID
which is the selected ID of the node on the treeview and it is always selected
0
 

Author Comment

by:Niall292
Comment Utility
I just discovered that the Success is called before the action is executed but the action is executed before the failure so both will be false, now I just need to know how to fix it
0
 

Author Comment

by:Niall292
Comment Utility
I still am pretty new to MVC, jqery and ajax.
 Am I reading this wrong. I am post to a controller/Action with the line

POST http://localhost:51050/Deviations/Delete/18776

but I am getting an error below that I am missing the id
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'MvcRoster.Controllers.DeviationsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.<br>Parameter name: parameters

Open in new window

Is the id not the last part of the link (18776)
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
Few things I can see. In your original post, you have this code:

function DeleteDeviation () {
   $.ajax({
      url: "/Deviations/Delete/" + Recordid, 
      type: "POST",                   
      success: function(result) {
         getRemarks();
      },
      failed: function(c) {
         alert(c.text);
      }
   });
}

Open in new window

2 things wrong. You're not setting the Recordid variable anywhere, so calling the Delete action would cause your 'null entry' problem. You also try and handle the errors with an argument called failed. This doesn't exist - it should be error
:

error: function(c) {
   alert(c.text);
}

Open in new window

Later on you do pass the RecordID variable into your function, but then refer to it with the wrong name. You pass in recID and then try using Recordid. You then try and assign the status of the AJAX call to the recID variable (!!). Finally you try and remove the row using the data() attribute - again (!!)

function DeleteDeviation (recID) {
   $.ajax({
      url: "/Deviations/Delete/" + Recordid, 
      type: "POST",
      success: function(result,recID) {
         ...

Open in new window

0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:Niall292
Comment Utility
This is the way my function is at the moment. Is this wrong

    function DeleteDeviation () {
        $.ajax({
                   url: "/Deviations/Delete/" + Recordid, 
                   type: "POST",  
                   datatype: "html",                                                
                   success: function(result) {
                    $("tr").data(Recordid).remove()
                    },
                    failed: function(c) {
                        alert(c.text);
                    }               
                });

Open in new window

0
 
LVL 42

Accepted Solution

by:
Chris Stanyon earned 167 total points
Comment Utility
Very!

Firstly: The variable called Recordid is never set to anything, so you are calling your Delete method with no arguments.

Secondly: There is no setting in $.ajax() called failed. For error handling you use a setting called error

Thirdly: On error you are trying to alert the text property of the jqXHR object (c.text) - it doesn't have a text property!

Fourthly: You can't call the remove() method on an element like you do. It will error out.

If you want to call the Delete method in a separate function like this, you will need to pass in some information so that the function knows what to delete. The fact that you want to remove the row after the record is deleted, it makes sense to pass the whole row in.

Without seeing your HTML, I can't be exact, but something like this is what you need. Have a good read through it and ask if you don't understand something:

$(document).ready(function() {
	$('.delete-record').click(function(e) {
		//prevent the default behaviour
		e.preventDefault();
		
		if ( confirm("Are you sure you want to delete this record?") ) {
			$thisRow = $(this).closest('tr');
			//call the delete function, with the current row being passed as an argument
			DeleteDeviation( $thisRow );
		};
	});
});
			
function DeleteDeviation( $rowToDelete ) {
	//get the ID from the data-id attribute of the row
	recordID = $rowToDelete.data('id');

	//make the AJAX call
	$.ajax({
		url: "/Deviations/Delete/" + recordID, 
		success: function(response) {
			//we have success from the AJAX call, so lets remove the row
			$rowToDelete.remove();
			//and log the output
			console.log(response);
		},
		error: function(jqXHR, textStatus, errorThrown) {
			//just in case things go pear shaped :)
			alert(textStatus + ' : ' + errorThrown);
		}
	});
}

Open in new window

0
 

Author Comment

by:Niall292
Comment Utility
@Chris
There is an argument passed by Recordid.
 I'm not at my computer at the moment but will post it tomorrow.
 The delete part does work but the "success or failure are never called in the Ajax function.


Although your code seems a lot cleaner and I will try it tomorrow and definitely let you know how it goes.

Thanks
0
 

Author Comment

by:Niall292
Comment Utility
I found in one of my comments above where Recordid gets its value
<script type="text/javascript" >
    $(document).ready(function() {
        $('.delete-record').click(function() {
            $(this).closest("tr").css("background-color", "#00FFFF");
            Recordid = $(this).closest("tr").data("id");
            if (confirm("Are you sure you want to delete this record")) {
                DeleteDeviation();

            }
            $(this).closest("tr").css("background-color", "white")
        })

    });
</script>

Open in new window

0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
True. Your Recordid variables does get it's value, but that variable is never passed into the DeleteDeviation() function, so that function is completely unaware of it.

Variables have a 'scope' meaning they only exist in the function they're declared in. Once the function is finished, the variable is destroyed. The exception to this is if you use Global variables, but under normal circumstances, that's considered bad practice. If you need another function to know about your variable, you need to pass it as an argument.

To pass your variable into the function, you call it like this:

DeleteDeviation(Recordid);

You must also make sure your DeleteDeviation() is defined in a way that accepts the variable:

function DeleteDeviation(RecordID) {
   alert (RecordID);
}

Open in new window

Try my code - it will make things a lot easier :)
0
 

Author Comment

by:Niall292
Comment Utility
Chris,
I copied and pasted your code in and I still get nothing.
I press delete watch it in Firebug it goes through the step reaches Success and jumps over it then goes to error once on error it seems to run the function or something then when it goes back to error it jumps over it as well but if I refresh the page the record is gone just like before.
I know I'm making a schoolboy mistake somewhere but just don't know where
0
 

Author Comment

by:Niall292
Comment Utility
This is a copy of the error shown in firebug console

"NetworkError: 500 Internal Server Error - http://localhost:51050/Deviations/Delete/9492"

Which doesn't tell you much
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
OK.  It sounds like the jQuery part of your script is working as it should (it's making the call and handling the response), but the server is generating an error. Unfortunately FireBug only shows what goes on in the browser (the client) and not what goes on with the the server, so you'll need to debug your server code some other way.  

The fact that the record is being deleted from the database tells me that the server script is receiving the Recordid properly and running the delete query, so your error lies somewhere after that part of your server-side script.

That is more likely to be an ASP problem than a jQuery problem though, so if you can't see what's wrong, you'll probably be better off asking a new question about your server-side script in the ASP zones.
0
 

Author Comment

by:Niall292
Comment Utility
Actually it's throwing an error now:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object

Open in new window

Here:
Line 39: <% foreach (MvcRoster.Models.DeviationDetails deviation in Model.GetDeviationDetails)

Open in new window


Models is coming back null.
I am wondering would it be taking the id field from Delete and passing it on to the getDeviations function.
Although I thought there wouldn't be a refresh but it seems that is what it is trying to do
0
 

Author Comment

by:Niall292
Comment Utility
Thanks for your help Chris,
but can you help why is getDeviation being called when it fills the table in the first place and I thought the whole idea of removing the record was to avoid a round trip.
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
As I said, this is now an ASP issue, not a jQuery one, and unfortunately I don't use ASP.

In theory, all your ASP script needs to do is read the value being passed in (the Record ID) and delete a row from the DB. It would probably make sense to then echo out the result, such as "Record Deleted OK", but it doesn't need to do anything else.

It seems that your script is already running the delete query because when you refresh, the record has gone, so anything after that part of your script seems redundant, and that's where you're getting your error.

If you need specific help on your ASP script, then you should post a new question about it in the ASP zones - you're much more likely to get an answer to the problem.
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
Niall.

I have no idea why getDeviation is being called - you must be asking for it somewhere in your script. As I said, the Delete script on your server should only delete the record and then echo (output / write) a response ("Done!") - nothing else.
0
 

Author Comment

by:Niall292
Comment Utility
Ok, well thanks again
0
 

Author Closing Comment

by:Niall292
Comment Utility
With your help I was able to get a work around but I still have the issue of none of my success or failures (errors) are firing
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
I think it's time you hired a professional developer - we tried exhaustively to help you out here, but to no avail.

You seem to be trying to go way beyond your scope of understanding, so I would suggest you start your learning process with something straight simple and forward.

If you're going to do any kind of development, then you absolutely must get a handle on some fundamentals, regardless of the programming language you choose. Functions and variables and how they relate is one of the first things you should learn. Without this knowledge, you will fail at every turn - I guarantee it.

As for web development, you really need to understand how the server and client talk to one another, and the limitations of both.

The EE guidelines ask that if you give a grade of anything less than A, that you explain why. Please do that. The reason things aren't working for you is down to your own knowledge, not our answers!
0
 

Author Comment

by:Niall292
Comment Utility
Chris,
I do half agree with you but if you had read the full question at the start you would have seen I said the record was getting deleted but success or failure was getting jumped over.

I do agree that you gave me a lot of good advice (and thank you) and that is why points were awarded, but I still have the original problem.
That is why it didn't get an A
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
We've covered this several times already - your server was causing an error so your jQuery should handle that error, but you had no error handler in place. You had a property called 'failed' in your jQuery. That property doesn't exist. It's called 'error', so when your server failed, it had no where to go, which is why it was jumping over everything. That's was your problem (one of them anyway!)
0
 

Author Comment

by:Niall292
Comment Utility
Chris,
I had tried 'error' at the start then reading other sites I tried failed (which maybe should have been fail) which apparently came out after 1.8
but like I said I definitely learned a lot from this but the original problem did not get fixed.
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
You're confusing the 'error' property with the fail() method. You tried using a non-existing 'failed' property!

It's very difficult for us to explain how to fix your problem because of some fundamental gaps in your knowledge. We do try out best, but sometimes it's just beyond the scope of understanding of the author. The best we can do there is direct them to some learning resources and hope that the penny drops.

Good luck with it ;)
0
 

Author Comment

by:Niall292
Comment Utility
Chris,
I appreciate all you guys do and have been helped out quite a few times on this site and it's like I said before I am new to jquery ajax and I admit there are gaps in my knowledge (some possibly very big gaps)
 but Thanks again and I apologise if it seemed your help was not appreciated because it was and if I could change it to an 'A' I would.

Good luck, and if you see any questions from me in the future hopefully you wont ignore them.
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
I won't ignore them :)
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

PROBLEM: The other day I was working on adding an ajax request to a webpage that already had a dialog box on the page.  The dialog box was using relative positioning to be positioned next to a form field I had on the page.  Everything was working…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now