If there's no download attribute, the filename for your download will solely depend on the HTTP header Content-Disposition sent by the server that's providing the file. The information from this header might also take precedence even if the download attribute is present.
A link-based solution conforms well to HTML standards and lets the browser do most of the work. However, if you want more control over the download and would like to display some custom progress indicator you can also download files via Angular's HttpClient. A file is best represented as a Blob in the browser:. The Blob object represents a blob, which is a file-like object of immutable, raw data -- MDN web docs.
By specifying the responseType option we can perform a GET request returning a blob representing the downloaded file. Let's assume we've got a designated DownloadService doing just that:. A component would then be able to call this service, subscribe to the corresponding observable and eventually save the file like this:.
Here, we're creating an anchor tag programmatically when the blob arrives. With URL. Finally, we click the link like the user would've done with a regular browser download link. After the file is downloaded, we'll discard the blob by revoking the object URL we created.
This approach is pretty verbose though and might not work smoothly for every browser. Therefore I'd advise you to use the popular library FileSaver. The saving then becomes a one-liner:. If you don't like adding a dependency for this and would prefer to use the manual approach shown before, you might as well refactor the code for saving the blob into a separate service. You can also create a custom injection token for URL - also see below how we'll do this for FileSaver.
By setting the option observe to events while making an HTTP request, we won't just receive the final response body of the request but also get access to intermediate HTTP events. We also need to explicitly pass the option reportProgress in order to receive HttpProgressEvents. Our HTTP request will eventually look like follows:. Since we don't just want to forward these events to every component, our service has to do some more work.
Otherwise our component would have to deal with HTTP specifics - that's what services are for! Instead let's introduce a data structure representing a download with progress:. A Download can be in one of three states. Either it hasn't started yet, therefore it's pending. Otherwise it's done or still in progress. This should work like this ;- — Thierry Templier. Hi ThierryTemplier, I'm getting "Constructors for derived classes must contain a 'super' call.
And thank you for a great solution — Spock. ThierryTemplier hi, thanks for replying.. I'm having more trouble getting blobs to be read, because response. I'm using the same code as you wrote here.. Hi again - sorry for spamming you all - just an update. Not the most elegant solution, but it works. Show 8 more comments. Spock Spock 2, 28 28 silver badges 26 26 bronze badges.
Any workaround with angular-cli? I even had to request the specific feature for the 3rd party plugin Angular2 Datepicker to make it works with angular-cli. I'm not sure how angular-cli works regarding 3rd party imports.
As far as I know it uses systemJs, and I know from manually playing with that, that it should be possible to configure it to import external dependencies. But I'm not sure how angular-cli does it I found this conversation although pretty old about how to manually add libraries using ng2-cli, but haven't tried myself: github.
How did you import Filesaver. I am having issues stackoverflow. Hey sorry man, I didn't see your comment until now.. Get; requestOptions. Save using fileSaver. File type: ", file. Indev Indev 81 1 1 silver badge 5 5 bronze badges. This should be the answer -- it allowed me to use authorization on the get without having to extend Xhr and worked just as well as the top answer.
What is this 'saveAs' function here? If it is github. Can you include the imports that you've used? Here is the simplest way to download a file from an API that I was able to come up with. Shashank Shekhar Shashank Shekhar 3, 2 2 gold badges 39 39 silver badges 50 50 bronze badges.
Types of property 'responseType' are incompatible. Type 'ResponseContentType' is not assignable to type '"json"'. BenDonnelly It should be this. Thom Kiesewetter Thom Kiesewetter 4, 2 2 gold badges 22 22 silver badges 33 33 bronze badges. Note: http call from client needs to support blob response. Dilip Nannaware Dilip Nannaware 1, 1 1 gold badge 14 14 silver badges 23 23 bronze badges. CreateResponse HttpStatusCode.
I added a dotnet core piece of code for that below. I got a solution for downloading from angular 2 without getting corrupt, using spring mvc and angular 2. Here I am sending byte[] array has return type from the controller. This will give you xls file format. If you want other formats change the mediatype and file name with right extension. I was facing this same case today, I had to download a pdf file as an attachment the file shouldn't be rendered in the browser, but downloaded instead.
To achieve that I discovered I had to get the file in an Angular Blob , and, at the same time, add a Content-Disposition header in the response. Well, I wrote a piece of code inspired by many of the above answers that should easily work in most scenarios where the server sends a file with a content disposition header, without any third-party installations, except rxjs and angular. As you can see, it's basically pretty much the average backend call from angular, with two changes.
Once the file is fetched from the server, I am in principle, delegating the entire task of saving the file to the helper function, which I keep in a separate file, and import into whichever component I need to. There, no more cryptic GUID filenames! We can use whatever name the server provides, without having to specify it explicitly in the client, or, overwrite the filename provided by the server as in this example. Also, one can easily, if need be, change the algorithm of extracting the filename from the content-disposition to suit their needs, and everything else will stay unaffected - in case of an error during such extraction, it will just pass 'null' as the filename.
As another answer already pointed out, IE needs some special treatment, as always. But with chromium edge coming in a few months, I wouldn't worry about that while building new apps hopefully. There is also the matter of revoking the URL, but I'm kinda not-so-sure about that, so if someone could help out with that in the comments, that would be awesome. You may also download a file directly from your template where you use download attribute and to [attr. This simple solution should work on most browsers.
This answer suggests that you cannot download files directly with AJAX, primarily for security reasons. So I'll describe what I do in this situation,.
Add href attribute in your anchor tag inside the component. Do all following steps in your component. If a tab opens and closes without downloading anything, i tried following with mock anchor link and it worked. You can return a Blob object from the server and create an anchor tag and set the href property to an object URL created from the Blob. Now clicking on the anchor will download the file.
You can set the file name as well. Stack Overflow for Teams — Collaborate and share knowledge with a private group. Create a free Team What is Teams? Collectives on Stack Overflow. Learn more. How do I download a file with Angular2 or greater Ask Question. Asked 5 years, 9 months ago. Active 1 month ago.
Viewed k times. Basil 1, 12 12 silver badges 19 19 bronze badges. You cannot download large files with this method. You will hit the memory limit per tab. This may be as low as GB. For large file downloads you need to specify a new tab e. I don't think there's a clean way to get around the large file size limitation with Ajax-style requests. Add a comment.
Active Oldest Votes. One of the many ways that exist to solve this is as follows: this. Amr ElAdawy 3, 5 5 gold badges 32 32 silver badges 49 49 bronze badges. Alejandro Corredor Alejandro Corredor 2, 1 1 gold badge 8 8 silver badges 6 6 bronze badges. What is this. Burjua the getReport returns a this. The issue I'm having is that the window opens and closes immediately not downloading the file — Braden Brown.
How can we set file name in here? I've used the above code for downloading a file from API response but i'm getting some error in creating the Blob part "Type response is not assignable to type Blobpart". Kindly help if anyone knows this issue — knbibin. Show 10 more comments. Try this! Hector Cuevas Hector Cuevas 1, 1 1 gold badge 6 6 silver badges 3 3 bronze badges. I used step 2 in combination with the answer from Alejandro and it worked without the need to install file-saver Thank you!
It works perfectly! I wonder if we can get the filename that is defined on the header of the response. Is that possible? This one however is not suitable for big files download. Can someone please tell why this answer is downvoted? The topic is to download a file using angular2.
If this method works to do a simple download then it should also be marked as a valid answer. SaurabhShetty, This won't help in case you want to send custom headers, what if you want to send an auth token for example? If you look into OP question you can see he uses authHttp!
I do understand the downvotes, nevertheless this answer solved my issue. If you let the server return the url in some context, the server could prepare the url. The cover could be a url to an image in the server.
0コメント