nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
67.32k stars 7.59k forks source link

How to return a pdf file in response ? #1090

Closed maroodb closed 6 years ago

maroodb commented 6 years ago

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 ?
       }
    }
marcus-sa commented 6 years ago

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

maroodb commented 6 years ago

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)
}
})
}));

}
}
marcus-sa commented 6 years ago
@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 :)

maroodb commented 6 years ago

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 ;)

marcus-sa commented 6 years ago

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

nightmarelie commented 5 years ago

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.

lock[bot] commented 5 years ago

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.