I have a controller action which renders a partial view:
public ActionResult Details(int id)
{
DetailsViewModel model =
ModelBuilder.GetDetailsViewModel(id, _repository);
return PartialView("Details", model);
}
and I'm loading the returned content into a dynamic element as follows:
$container = appendContainer(); // adds a div to the dom with the correct id
$container.load("MyController/Details", function(response, status, xhr) {
if (status != "success") {
$(container).html('an error has occured');
}
});
so this creates a div, and then loads the returned content into that div.
I want to alter this slightly so that the container div is only created if the call to the controller is succesful.
So:
I'd appreciate any pointers on how I could best acheive this.
in your case i would use $.ajax instead of .load() gives you more control over the flow + feels more clean
$.ajax({
url: "MyController/Details",
type: "GET",
success: function (response, status, xhr)
{
var jqContainer = appendContainer();
jqContainer.html(response);
},
error:function(XMLHttpRequest, textStatus, errorThrown)
{
//show the error somewhere - but this is a bad solution
}
});
concerning the error state - i also hate relying on exceptions - ugly and inefficient, you have several ways to handle this:
in my code i use $(document).ajaxSend(..) to globally check all Ajax responses for 278 code and show the error messages if there is any, or call the original hooked success function.
To return the error from the action i use the following result
public class AjaxErrorWithDetailsResult : JsonResult
{
public object ErrorResult { get; set; }
public AjaxErrorWithDetailsResult(object errorResult)
{
this.ErrorResult = errorResult;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
this.Data = ErrorResult;
context.HttpContext.Response.StatusCode = 278;
base.ExecuteResult(context);
}
}
where ErrorResult can be an anonymous object or an object that implement an interface with a property of ErrorMessage so you will know what to look for at the JS
All load
does is return HTML from a server, so why not just append to a temporary div and then get the HTML from it on success?
var $dummy = $("<div>");
$dummy.load("MyController/Details", function(response, status, xhr) {
var $container = appendContainer();
if (status != "success") {
$container.html('an error has occured');
}
else
{
$container.html($dummy.html());
}
$dummy.remove();
});
UPDATE:
If you're expecting an exception then you should handle it. If you're basically allowing the error to occur just to get status != "success"
then that's a serious code smell. You should catch the error and return a different PartialView.
public ActionResult Details(int id)
{
try
{
DetailsViewModel model =
ModelBuilder.GetDetailsViewModel(id, _repository);
return PartialView("Details", model);
}
catch (SomeException ex)
{
return PartialView("Error", ex.Message);
}
}
Then you're guaranteed to always get a valid HTML response and if you don't, then your basic error an error occured
will come into play.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With