0

I have a ajax form in which I would like to call two different javascript functions, one for success and one for failure. In both of these calls, I pass data back from the server to the javascript. Please note the following:

I have this in my view

@using (Ajax.BeginForm("MyAction", null,
new AjaxOptions
{
    HttpMethod = "POST", // HttpPost
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "myDiv", 
    OnSuccess = "callSuccess(data.msg)",
    OnFailure = "callFailure(data.msg)",
}, new { @class = "form-inline" }))
{
   ... // my content
}

My controller has the following logic when return the post.

    public ActionResult MyAction(string myString)
    {
        ...
        // If error occurred
        return Json(new { success = false, msg= "Fail" });
        ...
        // If no errors
        return Json(new { success = true, msg= "Success" });
    }

No matter what is returned, OnSuccess is the only one that gets called. What is the proper way to call OnFailure?

Community
  • 1
  • 1
usr4896260
  • 1,427
  • 3
  • 27
  • 50
  • Your returning valid data (not throwing an exception or returning an error code) so it will always go to the success function. –  May 19 '16 at 01:59
  • "success" means that the ajax call was successful - ie the http request/receive process completed without an http error. AJAX doesn't know that you have a "success" property set to false. – freedomn-m Oct 09 '19 at 07:40

3 Answers3

2

Consider Using HTTP Status Codes

You could consider returning the appropriate HTTP status code that corresponds with the type of error you want to trigger (i.e. Unauthorized, Bad Request, etc.) by returning an HttpStatusCodeResult object :

// If an error occurred...
if(error)
{
     // Indicate your code and error message. This uses the Bad Request status (400) 
     return new HttpStatusCodeResult(400, "Something went wrong...");
}

Handling This Client-Side

If you didn't want to do this, you could consider defining a single result event (i.e. OnSuccess = "call(data);) and then within that event, check your success property to determine what to do :

function call(data){
      if(data.success){
          callSuccess(data.msg);
      }
      else{
          callFailure(data.msg);
      }
}
Rion Williams
  • 74,820
  • 37
  • 200
  • 327
2

With the help from Rion Williams post, I was able to call both functions. More importantly, I figured out how to access and display the desired message upon success/failure:

My controller

public ActionResult MyAction(string myString)
{
    ...
    // If error occurred
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Error occurred!");
    ...
    // If no errors
    return Json(new { success = true, msg= "Success" });
}

My view:

@using (Ajax.BeginForm("MyAction", null,
new AjaxOptions
{
    HttpMethod = "POST", // HttpPost
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "myDiv", 
    OnSuccess = "callSuccess(data.msg)",
    OnFailure = "callFailure(error)",    // error = "Error occurred!"
}, new { @class = "form-inline" }))
{
   ... // my content
}
usr4896260
  • 1,427
  • 3
  • 27
  • 50
  • 1
    This will no longer work with HTTP/2 as noted here: https://stackoverflow.com/questions/46922043/custom-error-message-with-httpstatuscoderesult-not-working-on-localhost – mikeschuld Mar 26 '18 at 19:29
  • This also depends on what went wrong in the "if error" part. Was it really a bad request? Or did something else go wrong (eg disk full would not be a "bad request"). Use the correct HttpStatusCode. – freedomn-m Oct 09 '19 at 07:43
1

Yes it will always call OnSuccess. But you can check your success Property inside onSuccess function.

    OnSuccess : function (data)
 {                     
    if(success)
    {
    alert('Json Return Success')
    }
    else
    {
    alert('json Result False')
    }

}

Otherwise you have to send error status as Rion Williams mention

Sudip Thapa
  • 120
  • 1
  • 10
  • If that's the case, is there a purpose for the `OnFailure` Ajax option? Or is it triggered by returning a `HttpStatusCodeResult` ? – usr4896260 May 18 '16 at 21:53
  • 1
    If any error comes up during run time then instead of onSuccess it goes to OnFailure. You can also add error like this as well.. ModelState.AddModelError("", "Enter all the values");. I hope it goes to onFailure – Sudip Thapa May 19 '16 at 00:52