Solved

Why is Ajax Success or Failure not being called

Posted on 2014-02-07
42
569 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 25
  • 10
  • 4
  • +1
42 Comments
 
LVL 53

Expert Comment

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

Author Comment

by:Niall292
ID: 39842986
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
ID: 39843019
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
Tutorials alone can't teach real engineering

So we built better training tools.

-Hands-on Labs
-Instructor Mentoring
-Scenario-Based Tests
-Dedicated Cloud Servers

All at your fingertips. What are you waiting for?

 

Author Comment

by:Niall292
ID: 39843027
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 53

Expert Comment

by:Scott Fell, EE MVE
ID: 39843029
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
ID: 39843031
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
ID: 39843040
@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
ID: 39843044
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
ID: 39843045
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
ID: 39843049
Yes it would be in the success callback
0
 

Author Comment

by:Niall292
ID: 39843051
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
ID: 39843062
@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
ID: 39843063
<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
ID: 39843091
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
ID: 39843204
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 53

Expert Comment

by:Scott Fell, EE MVE
ID: 39843264
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
ID: 39843287
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
ID: 39843338
@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
ID: 39843519
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
ID: 39844492
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 43

Expert Comment

by:Chris Stanyon
ID: 39844700
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
 

Author Comment

by:Niall292
ID: 39844709
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 43

Accepted Solution

by:
Chris Stanyon earned 167 total points
ID: 39844727
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
ID: 39846056
@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
ID: 39846059
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 43

Expert Comment

by:Chris Stanyon
ID: 39846117
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
ID: 39847098
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
ID: 39847105
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 43

Expert Comment

by:Chris Stanyon
ID: 39847129
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
ID: 39847165
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
ID: 39847174
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 43

Expert Comment

by:Chris Stanyon
ID: 39847177
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 43

Expert Comment

by:Chris Stanyon
ID: 39847182
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
ID: 39847211
Ok, well thanks again
0
 

Author Closing Comment

by:Niall292
ID: 39858711
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 43

Expert Comment

by:Chris Stanyon
ID: 39858735
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
ID: 39858813
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 43

Expert Comment

by:Chris Stanyon
ID: 39858844
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
ID: 39858878
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 43

Expert Comment

by:Chris Stanyon
ID: 39858919
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
ID: 39858958
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 43

Expert Comment

by:Chris Stanyon
ID: 39858965
I won't ignore them :)
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Introduction If you're like most people, you have occasionally made a typographical error when you're entering information into an online form.  And to your consternation, the browser remembers the error, and offers to autocomplete your future entr…
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…

729 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