Nest: How to return a pdf file in response ?

Created on 14 Sep 2018  路  7Comments  路  Source: nestjs/nest

we suppose that I have a Buffer object , How to return it in a response object?

@Get(':fileHash')
getFile(@Param('fileHash') fileHash) {
        console.log(fileHash);
        this.sharingService.get(fileHash).then ( buffer => {

         // what to do ?
       }
    }

Most helpful comment

That's how I implemented it on my project

Controller:

import { Post, Body, Res } from '@nestjs/common';
import { Response } from 'express';
// import PrintDto | printSchema | JoiValidationPipe

@Post('pdf')
async print(
  @Body(new JoiValidationPipe(printSchema)) body: PrintDto,
  @Res() res: Response,
) {
  const buffer = await this.printService.printPdf(body);
  const stream = this.printService.getReadableStream(buffer);

  res.set({
    'Content-Type': 'application/pdf',
    'Content-Length': buffer.length,
  });

  stream.pipe(res);
}

PrintService:

import { Readable } from 'stream';
// import PrintDto

async printPdf(body: PrintDto): Promise<Buffer> {
  // ...
  return buffer;
}

getReadableStream(buffer: Buffer): Readable {
  const stream = new Readable();

  stream.push(buffer);
  stream.push(null);

  return stream;
}

useful link to stream-handbook This document covers the basics of how to write node.js programs with streams.

All 7 comments

Could you provide some more details?
Like the code for SharingService?
Usually you'd pipe the readable stream to the response object and set the Content-Type header to application/pdf

this is sharingService code:

@Injectable()

export class SharingService {
private ipfs: any;
constructor (){
this.ipfs = ipfsAPI('localhost', '5001', {protocol: 'http'})
}
public add (file) {
this.ipfs.add(file, (err, res) => {
console.log(err);
console.log(res);
})
}

public get (fileHash) {
return new Promise(((resolve, reject) => {
this.ipfs.get(fileHash, (err, res) => {
if (err) {
reject(err)
} else {
resolve(res)
}
})
}));

}
}
@Injectable()
export class SharingService {
    private ipfs: any;

    constructor (){
        this.ipfs = ipfsAPI('localhost', '5001', { protocol: 'http' });
    }

    // Get the file content as a readable stream
    public async get(fileHash: string) {
        return await this.ipfs.files.catReadableStream(fileHash);
    }
}
// And then pipe it through the request response and set the content-type header
// dunno if this works
@Get(':fileHash')
@Header('Content-Type', 'application/pdf')
async getFile(@Param('fileHash') fileHash: string) {
   return await this.sharingService.get(fileHash);
}

// but this will definitely work
@Get(':fileHash')
@Header('Content-Type', 'application/pdf')
async getFile(@Res() res: Response, @Param('fileHash') fileHash: string) {
   res.pipe(await this.sharingService.get(fileHash));
}

This is not a Q/A forum, go on https://stackoverflow.com next time you need help with coding :)

Thank you for your answers but it dosen't answer the question.

catReadableStream return a json object without buffer, I think converting buffer into file and return it in response is easier, I will post the question in stackoverflow ;)

I think you need to formulate your question different as I got no clue what you actually want then.
You're overcomplicating things a lot.
catReadableStream returns a ReadableStream which will then be piped to the Response

That's how I implemented it on my project

Controller:

import { Post, Body, Res } from '@nestjs/common';
import { Response } from 'express';
// import PrintDto | printSchema | JoiValidationPipe

@Post('pdf')
async print(
  @Body(new JoiValidationPipe(printSchema)) body: PrintDto,
  @Res() res: Response,
) {
  const buffer = await this.printService.printPdf(body);
  const stream = this.printService.getReadableStream(buffer);

  res.set({
    'Content-Type': 'application/pdf',
    'Content-Length': buffer.length,
  });

  stream.pipe(res);
}

PrintService:

import { Readable } from 'stream';
// import PrintDto

async printPdf(body: PrintDto): Promise<Buffer> {
  // ...
  return buffer;
}

getReadableStream(buffer: Buffer): Readable {
  const stream = new Readable();

  stream.push(buffer);
  stream.push(null);

  return stream;
}

useful link to stream-handbook This document covers the basics of how to write node.js programs with streams.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tronginc picture tronginc  路  3Comments

marshall007 picture marshall007  路  3Comments

rlesniak picture rlesniak  路  3Comments

cdiaz picture cdiaz  路  3Comments

anyx picture anyx  路  3Comments