Q:

Jquery file download no callback working

I am using the jquery.filedownload plugin with asp web api to download a file and display error message from the server.
I have setup the plugin and added cookies to my response as indicated on github: https://github.com/johnculviner/jquery.fileDownload
My file is being downloaded successfully, however callbacks are not working.
Js
var url = "/WebApi/PayrollBatches/GetBatchCsv?batchId=" + batchId;
$.fileDownload(url, {
 successCallback: function (url) {
       alert('success');
 },
 failCallback: function (responseHtml, url) {
        alert('error');  
 }
 });
return false; 
//this is critical to stop the click event which will trigger a normal file download!

Asp Web Api
        [HttpGet]
    public async Task<HttpResponseMessage> GetBatchCsv(int batchId)
    {
        string csv;
        try {
            using (var Dbcontext = new RossEntities()) {
                PayrollBatchExport dal = new PayrollBatchExport(Dbcontext);
                csv = await dal.GetBatchCsv(batchId);
            }
        }
        catch (Exception ex) {
            HttpError myCustomError = new HttpError(ex.Message) { { "CustomErrorCode", 42 } };
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, myCustomError);
        }

        var cookie = new CookieHeaderValue("fileDownload", "true");
        var cookiePath = new CookieHeaderValue("path", "/");
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

        response.Content = new StringContent(csv);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        response.Content.Headers.ContentDisposition.FileName = "Export.csv";
        response.Headers.AddCookies(new CookieHeaderValue[] { cookie, cookiePath });
        response.StatusCode = HttpStatusCode.OK;

        return response;
    }

Edit
Below is what my browser console looks like when the server responds with error 500:

A:

OK, after spending some time with Fiddler, the problem was with a cookie. Notice this code inside the jquery.fileDownload.js:
function checkFileDownloadComplete() {
    //has the cookie been written due to a file download occuring?

    var cookieValue = settings.cookieValue;
    if (typeof cookieValue == 'string') {
        cookieValue = cookieValue.toLowerCase();
    }

    var lowerCaseCookie = settings.cookieName.toLowerCase() + "=" + cookieValue;

    if (document.cookie.toLowerCase().indexOf(lowerCaseCookie) > -1) {

        //execute specified callback
        internalCallbacks.onSuccess(fileUrl);
...

The success callback is being called only if server returns a cookie as project page says, however the API controller wasn't returning this cookie correctly. This code works well for me and is also described of official docs
public class PayrollBatchesController : ApiController
{
    [HttpGet]
    public async Task<HttpResponseMessage> GetBatchCsv(int batchId)
    {
        string csv;
        try
        {
            string path = System.Web.HttpContext.Current.Request.MapPath(@"~\Files\testfile.csv");
            csv = File.ReadAllText(path);// await dal.GetBatchCsv(batchId);

        }
        catch (Exception ex)
        {
            HttpError myCustomError = new HttpError(ex.Message) { { "CustomErrorCode", 42 } };
            HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, myCustomError);
            errorResponse.Content = new StringContent("error: " + ex.ToString());
            return errorResponse;
        }

        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

        // Set Cookie
        var cookie = new CookieHeaderValue("fileDownload", "true");
        cookie.Expires = DateTimeOffset.Now.AddDays(1);
        cookie.Domain = Request.RequestUri.Host;
        cookie.Path = "/";
        response.Headers.AddCookies(new CookieHeaderValue[] { cookie });

        // -------------
        response.Content = new StringContent(csv);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        response.Content.Headers.ContentDisposition.FileName = "Export.csv";
        response.StatusCode = HttpStatusCode.OK;

        return response;
    }
}

Please note, that for demo purposes I am not retrieving CSV data from DAL but from a testing file as the above code shows. Also, to be complete here, I am attaching the client side code:
<body>
    <div> 
        <button id="btn" type="button">get</button>
    </div>
    <script src="~/Scripts/fileDownload.js"></script>
    <script>
        $(document).ready(function () {
            $('#btn').click(function () {
                var url = "/api/PayrollBatches/GetBatchCsv?batchId=1";
                $.fileDownload(url, {
                    successCallback: function (url) {
                        alert('success');
                    },
                    failCallback: function (responseHtml, url) {
                        alert('error');
                    }
                });
                return false;
            });
        });
    </script>
</body>

Edit: fail callback

