23

I have an angular2 project with an ASP.Net Web API. I have code to retrieve a file path from my database which goes to a document on my server. I then want to display this document in the browser in a new tab. Does anybody have any suggestions how to do this?

I am happy to retrieve the file in either Angular2 (Typescript) or in my API and stream it down.

This is my attempt of retrieving it in my API but i cannot work out how to receive it in Angular2 and display it properly:

public HttpResponseMessage GetSOP(string partnum, string description)
    {
        var sopPath = _uow.EpicorService.GetSOP(partnum, description).Path;
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var stream = new FileStream(sopPath, FileMode.Open);
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
        return result;
    }

Any help would be greatly appreciated.

Many Thanks!!!

6
  • If you want to see it in another tab, why not just open a new tab to the API's URL and let the browser interpret the content? You'd probably need to use a mime type of "application/pdf" instead of "application/octet-stream". Commented Oct 28, 2016 at 7:40
  • I wrote about getting and displaying pdf files in new tab in Angular 2 here, check out my answer: stackoverflow.com/questions/37046133/… Commented Oct 28, 2016 at 7:45
  • @StefanSvrkota would this work with my API as it is? Or would i need to make changes to return it in the right format? Commented Oct 28, 2016 at 7:46
  • I'm not sure, try it. I can let you know later how my API looks. Commented Oct 28, 2016 at 7:51
  • OK im just implementing it and ill let you know :) Commented Oct 28, 2016 at 7:52

4 Answers 4

44

First of all, you need to set options for your http request - set responseType to ResponseContentType.Blob, use blob() to read response as blob and set its type to application/pdf:

downloadPDF(): any {
    return this._http.get(url, { responseType: ResponseContentType.Blob }).map(
    (res) => {
            return new Blob([res.blob()], { type: 'application/pdf' })
        }
}

Then, in order to get the file, you need to subscribe to it and you can create new ObjectURL and use window.open() to open PDF in new tab:

this.myService.downloadPDF().subscribe(
        (res) => {
        var fileURL = URL.createObjectURL(res);
        window.open(fileURL);
        }
    );
Sign up to request clarification or add additional context in comments.

5 Comments

Hi,Stefan.It is showing me failed to to load PDF document.Please help me.I am using Angular4.
I could able to download but not able to show in the new browser tab.
return new Blob([res.blob()] saved my day, Thanks
Be careful if you're using an ad-blocker extension. Ad-blockers block blob URLs by default. As a result, e.g. in Chrome and Firefox, with the uBlock Origin extension, it would try to open the new window and close it automatically. You can read more about here: stackoverflow.com/questions/51272781/…
Also, if you care about this working in IE too, read this: stackoverflow.com/questions/24007073/…
14

Angular v.5.2.1 answer:

In *.services.ts

downloadPDF(): any {
    return this._httpClient.get(url, { responseType: 'blob'})
            .map(res => {
            return new Blob([res], { type: 'application/pdf', });
        });
  }

And then in *.component.ts

downloadPDF() {
    let tab = window.open();
    this._getPdfService
      .downloadPDF()
      .subscribe(data => {
        const fileUrl = URL.createObjectURL(data);
        tab.location.href = fileUrl;
      });
  }

Its important to initiate and open a new tab before calling the service. Then set this tabs url to the fileurl.

4 Comments

why is important to open the tab before calling the service instead of opening it with the objecturl as parameter (as shown in the selected answer)?
@PauFracés because you're not 'allowed' to open a tab "programatically", only users are allowed to open tabs, thus you must initiate a new tab as close as possible to the user interaction which happens when a user click on a button which then calls downloadPDF(). Inside the subscription is too far from the user interaction.
I'm getting Error Failed to load PDF document.
@jonas Can you take a look at this question. I have a similar question: stackoverflow.com/questions/55070184/…
5

ANGULAR 5

I had the same problem which I lost few days on that.

Here my answer may help others, which helped to render pdf.

For me even though if i mention as responseType : 'arraybuffer', it was unable to take it.

For that you need to mention as responseType : 'arraybuffer' as 'json'.(Reference)

Working code

service.ts

downloadPDF(): any {
return this._httpClient.get(url, { responseType: 'blob' as 'json' })
        .map(res => {
        return new Blob([res], { type: 'application/pdf', });
    });

}

component.ts

this.myService.downloadPDF().subscribe(
    (res) => {
    var fileURL = URL.createObjectURL(res);
    window.open(fileURL);
    }
);

Referred from the below link

https://github.com/angular/angular/issues/18586

1 Comment

How do I change it for my service call? stackoverflow.com/questions/55070184/…
0

Angular 2+ Example PDF-viewer

Page.html

<div class="container">
<div>
    <label>PDF src</label>
    <input type="text" placeholder="PDF src" [(ngModel)]="pdfSrc">
</div>
<div>
    <label>Page:</label>
    <input type="number" placeholder="Page" [(ngModel)]="page">
</div>
<div class="row">
    <div class="col-md-5">
        <div class="thumbnail" style="width: 150px;height: 200px;" (click)="pdfShow=!pdfShow">
            <p>click me to view PDF in Iframe!</p>
            <pdf-viewer [src]="pdfSrc"
                        [page]="page"
                        [original-size]="false"
                        style="display: block;"
             ></pdf-viewer>
        </div>
        <br>
    </div>
    <div class="col-md-7">
        <div *ngIf="!pdfShow">
            <h4>PDF in Iframe</h4>
            <iframe width="500" height="600" [src]="pageurl" type="application/pdf"></iframe>
        </div>
    </div>
</div>
<br><br>
<h2> PDF in Object Tag</h2>
<object width="500" height="600"  data="https://vadimdez.github.io/ng2-pdf-viewer/pdf-test.pdf" type="application/pdf"></object>

page.ts

import { Component } from '@angular/core';
import { BrowserModule, DomSanitizer, SafeResourceUrl } from '@angular/platform- 
browser'

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
 })
 export class AppComponent {

  pdfSrc = 'https://vadimdez.github.io/ng2-pdf-viewer/pdf-test.pdf';
  page: number = 1;
  pageurl: SafeResourceUrl;

  constructor(private domSanitizer: DomSanitizer) {
     }
      ngOnInit() {
      this.pageurl = this.domSanitizer.bypassSecurityTrustResourceUrl(this.pdfSrc);
     }
     title = 'Mohsen';
     }

app.module.ts

add

import { FormsModule } from '@angular/forms'; 
import { PdfViewerComponent } from 'ng2-pdf-viewer';
import { HttpModule } from '@angular/http';.
import {HttpClientModule} from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';

import the

imports: [
    BrowserModule,
    HttpClientModule,
    HttpModule,
    FormsModule,
    RouterModule.forRoot(appRoutes)
],

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.