Downloading a file in angular






















I am sure it is stupidly simple, but so far I am simply not grasping it. The code of the component function is below. I can't even find the definition of URL in window, but apparently it exists. If I use the FileSaver. So I guess this is something that changed recently or is not yet implemented. How can I trigger the file save in A2? For the sake of completeness, the service that fetches the data is below, but the only thing it does is to issue the request and pass on the data without mapping if it succeeds:.

The problem is that the observable runs in another context, so when you try to create the URL var, you have an empty object and not the blob you want. As mentioned by Alejandro Corredor it is a simple scope error. The subscribe is run asynchronously and the open must be placed in that context, so that the data finished loading when we trigger the download.

That said, there are two ways of doing it. As the docs recommend the service takes care of getting and mapping the data:. Then, on the component we just subscribe and deal with the mapped data. There are two possibilities. The first , as suggested in the original post, but needs a small correction as noted by Alejandro:.

The second way would be to use FileReader. The logic is the same but we can explicitly wait for FileReader to load the data, avoiding the nesting, and solving the async problem. Note: I am trying to download an Excel file, and even though the download is triggered so this answers the question , the file is corrupt.

See the answer to this post for avoiding the corrupt file. ArrayBuffer by default it ResponseContentType. Downloading file through ajax is always a painful process and In my view it is best to let server and browser do this work of content type negotiation. I am using Angular 4 with the 4. I modified an answer I found in Js' Technical Blog which creates a link object, uses it to do the download, then destroys it. The value of this. I am using this to download attachments, so I know the id, contentType and filename: I am using an MVC api to return the file:.

Inside downloadFile data function we need to make block, link, href and file name. I added in the file-saver as Hector Cuevas named in his answer. Using Angular2 v. The journal reducer Though this only sets the correct states used in our application I still wanted to add it in to show the complete pattern.

On the component part, you call the service without subscribing to a response. The solution is referenced from - here. I found the answers so far lacking insight as well as warnings. This is the complete example with the application part and service part after.

Note that we set the observe: "response" to catch the header for the filename. Also note that the Content-Disposition header has to be set and exposed by the server, otherwise the current Angular HttpClient will not pass it on.

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.

Thanks, works without needing any plugins etc. Saved my day, big thumbs up for you. You should pass this. Show 4 more comments. Andreo Andreo 11 3 3 bronze badges. J Scott J Scott 1 1 silver badge 6 6 bronze badges. Siddharth Siddharth 31 1 1 bronze badge. Aswathy 7 7 bronze badges. David Kroese David Kroese 13 5 5 bronze badges.

Sign up or log in Sign up using Google. Sign up using Facebook. Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog. Find centralized, trusted content and collaborate around the technologies you use most. Connect and share knowledge within a single location that is structured and easy to search. I've searched google and found some code base to download the file and I've used it in my application, but I'm getting some errors and unable to find it out the solution.

Below are my code base. Your call would then look like this:. I use this method to put the filename and the MIME Type of the arraybuffer in the Content-Disposition and Content-Type response headers and then use a generic download service at the client-side. Also, I would suggest using a File object instead of just the Blob , which gives you the flexibility of giving it a filename like so:. This will also solve the problem that knbibin raised about using a custom filename. 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. Asked 2 years, 1 month ago. Older browsers, like the Internet Explorer, might not recognize the download attribute. 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.



0コメント

  • 1000 / 1000