Performing file downloads through AJAX in AngularJS

Recently, I developed an AngularJS program to facilitate file downloads from the server. Below is the code:

HTML Code

<a download="fullList.csv" ng-href="{{ fullListUrl }}" type="button" class="btn btn-success btn-xs exec-batch"  ng-click="exportCSVBulk(batchExec)">
          <span class="glyphicon glyphicon-ok"></span> EXPORT AS CSV
</a>

AngularJS Controller

$scope.exportCSVBulk=function(){
 var page = "../importExportService/exportBulkCSV/"+batchExec.id;
 $http.get(page).success(function(response) {
 $scope.fullListUrl = 'data:text/csv;charset=utf-8,' + escape(response); 
});
}

My current approach involves triggering the exportCSVBulk function when a user clicks on the EXPORT AS CSV link, setting the URL value (fullListUrl) in the process. However, due to the nature of this being an Ajax request, there seems to be a delay in redirection upon clicking the link. Is there a solution to this issue, or perhaps an alternative method that can be implemented?

Answer №1

I have encountered a similar issue when trying to download files like .pdf, .xls, .xlsx etc through Ajax.

It is a known fact that files cannot be downloaded directly through Ajax, but I have found a solution that enables file downloads through Ajax.

You can utilize the jquery.fileDownload - A jQuery File Download Plugin for feature rich file downloads with an Ajax-like experience.

See Demo in Action

On the Server Side

For server-side processing, I am utilizing Spring framework.

@RequestMapping(value = "exportXLS", method = RequestMethod.POST, produces = APP_JSON)
@ResponseBody
public void getCSV(final HttpServletResponse response, @RequestParam(value = "empId", required = true) final String empId) throws IOException, Exception
{
    final byte[] csv = ExportXLSUtil.getFileBytes(empId); // obtaining the file bytes
    final OutputStream output = getOutputStream(response);
    response.setHeader("Content-Disposition", "attachment; filename=documents_" + new DateTime() + ".xls");
    response.setContentType(CONTENT_TYPE);
    response.setContentLength(csv.length);
    write(output, csv);
}

On the Client Side

For client-side scripting, I am using AngularJS.

$downloadXLS = function(id)
{
    $.fileDownload('/user/exportXLS', 
    {
        httpMethod : "POST",
        data : {
            empId : id
        }
    }).done(function(e, response)
    {
     // success
    }).fail(function(e, response)
    {
     // failure
    });
}

Download Link - Get jquery.fileDownload.js Here

Answer №2

I came up with a more geometric approach to solving the issue. In order to synchronize with server information, the server must provide content-type and content-disposition. However, it is also possible to manually add type and download properties.

 vm.export = function () {
            //PopUps.showLoading()
            $http.get(Url).then(function (result) {
                //PopUps.hideLoading()
                var headers = result.headers()
                var blob = new Blob([result.data], { type: headers['content-type'] })
                var windowUrl = (window.URL || window.webkitURL)
                var downloadUrl = windowUrl.createObjectURL(blob)
                var anchor = document.createElement("a")
                anchor.href = downloadUrl
                var fileNamePattern = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
                anchor.download = fileNamePattern.exec(headers['content-disposition'])[1]
                document.body.appendChild(anchor)
                anchor.click()
                windowUrl.revokeObjectURL(blob)
            })
        }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhance your user interface with Twitter Bootstrap and Angular.js by implementing a dynamic drop-down feature

How can I add a dropdown to a tab using angular.js and bootstrap? Here is the code I have: <tabset class="nav nav-tabs centered-tab sub-nav"> <tab heading="Bio" class="dropdown-toggle" > <ul class="dropdown-menu"> <li ...

Discover the latest method for retrieving the value of a hidden field using Selenium WebDriver in Java

My attempt to retrieve the hidden field value using the code below is resulting in the default value of 0.69163. WebElement hiddenInput = ieDriver.findElement(By.id("form_base_amount_input_hidden")); String currencyConverted = hiddenInput.getAttribute("va ...

The Bootstrap navbar is not aligning correctly and the collapse feature is not functioning properly

My first experience with Bootstrap is not going as expected. I am trying to create a navigation bar where the links align to the right, and when the screen size decreases, it changes to a hamburger menu on the right side. However, the links do not move to ...

Sharing environment variables between a React app and an Express.js server that hosts it as a static site can be achieved by setting

My static site react app is hosted under an express server project in a folder called client/build. The oauth redirect uris point to the express server for token retrieval. The react app redirects users to the oauth endpoint, which is also referenced by th ...

Formik Fields with unique key properties

When mapping text fields, I follow this structure: { AddVehicleFields.map(({formikRef, ...input}) => ( <> <TextField key={formikRef} helperText={ getIn(formik.touched, formikRef) ? getIn(formik. ...

Updating Angular 5 Views Dynamically Using a While Loop

I am facing an issue in my app where I have a progress bar that updates using a while loop. The problem is that the view only updates after the entire while loop has finished running, even though I am successfully changing the update progress value with ea ...

Dealing with a jQuery/Javascript/AJAX response: sending a string instead of an integer as a parameter to a

Trying to figure out how to handle passing integers as strings in JavaScript within an AJAX response. Here is the code snippet: message+="<td class='yellow' onclick='open_flag("+i+j+")'>"; The message variable is eventually inse ...

Sending a JavaScript array to a Ruby on Rails controller by utilizing a hidden form field

Having explored numerous solutions that did not fit or resolve my issue, I am turning to this platform with my question: I utilize JavaScript to populate hidden fields in a form with data and transmit it to a Ruby on Rails controller. While this process w ...

issue concerning slide functionality and ajax integration

I'm facing an issue with the structure of my HTML. Here is the setup I have: <div id ="slide1"> <form method="post" id="customForm" action=""> //my content - name, email, mypassword, pass2 </for ...

Having trouble establishing a connection between MongoDB Atlas, NodeJS, and Mongodb

Encountering an issue while attempting to establish a connection with MongoDB. The error seems to be related to the 'connect' keyword itself. I am unsure of what the exact problem is. The error message displayed is as follows: mongodb.connect( ...

Navigating through the execution of a program with the use of

As I navigate my way through learning express, a question has arisen regarding the mechanics of the next() function. Is my understanding correct that when next() is invoked, it immediately initiates the execution of app.get, while anything below next() ...

Troubleshooting Android Volley Response Problems

I encountered an issue while parsing a basic JSON response. The process goes smoothly when extracting the employer name, but it crashes at a certain point stating that my 'review' json object is empty. You can view the response here. Here is the ...

How do I reverse the black background and white foreground of the image signature stream/object in iText Reading?

I am having an issue with reading image objects from a PDF file. The images are appearing with a black background and white text, but I need them to be the opposite - white background with black text. How can I achieve this reversal in the image from the P ...

Amcharts displays individual balloons for each graph instead of a single balloon for all graphs

My goal is to have a single balloon for all stacked graphs. I modified my code according to this guide. Unfortunately, the data for messages is not being displayed. https://i.sstatic.net/2MRhc.jpg Did I make an error in my implementation? function creat ...

Upon my initial click of the delete button, all the notes vanished. However, after refreshing the page, everything was back to normal and functioning properly

After numerous attempts, I have exhausted almost all troubleshooting methods. I meticulously tested my API to rule out any issues related to it. Strangely, the problem only occurs upon initial page visit, but works flawlessly upon refreshing. Prior to cli ...

Is it possible to trigger a submit button to perform a POST request and an AJAX call simultaneously

I have a form that sends a POST request to show_aht2.php, but I also need it to trigger an AJAX call as shown in the code below. How can I achieve this without redirecting the user to another page? I want the user to remain on map.php. Thank you in advanc ...

Trigger Element Upon Click

Forgive me in advance for the lack of quality in this question, but I'll proceed anyway: All I want is for an element to slide open when clicked with a mouse! That's all! More specifically, I am looking for a single menu item that, upon clickin ...

UniformJS Select Control in AngularJS fails to refresh

I am in the process of developing an application with AngularJS and UniformJS. I want to include a reset button on the interface to bring my selects back to their default values. However, I am facing an issue if I use uniform.js. You can check out the pro ...

"Track the progress of a form submission with a loading indicator using Sweet

I am looking to incorporate a waiting time animation when submitting a form, and I prefer using SweetAlert over a traditional loading image. Here is the basic code snippet: $("form").submit(function (e) { e.preventDefault(); // prevents def ...

Managing control among various child popups

In the situation I am facing, a parent window with login fields is present. In order to manage its controls, I have stored the window handle using: String parentWindow = idriver.getWindowHandle(); After entering the login credentials, a new popup (let&ap ...