0

I am fairly new to nodeJs and loopback. I am trying to implement a feature that serves a csv stream to be downloaded in the client side once user clicks on "Export to csv" in Loopback 4. I have already implemented function that gives me the stream. I now need to send that to the client side as a csv file. Any ideas would be much appreciated. Thanks in advance.

Jestin
  • 1
  • 2

1 Answers1

0

import {Filter, repository} from '@loopback/repository';
import {
  post,
  param,
  get,
  getFilterSchemaFor,
  Response, // Import REST HTTP Response object
  RestBindings,
} from '@loopback/rest';
import {File} from '../models';
import {FileRepository} from '../repositories';
import {inject} from '@loopback/core';

export class FileController {
  constructor(
    @repository(FileRepository)
    public fileRepository: FileRepository,
    // Inject REST HTTP Response object into controller
    @inject(RestBindings.Http.RESPONSE)
    public response: Response,
  ) {}

  @get('/files/download', {
    responses: {
      '200': {
        description: 'File instance file download',
        content: {
          // See: https://swagger.io/docs/specification/describing-responses/
          'text/csv': {
            schema: {
              type: 'string',
              format: 'binary',
            },
          },
        },
      },
    },
  })
  async downloadById(
    @param.query.object('filter', getFilterSchemaFor(File))
    filter?: Filter<File>,
  ): Promise<string> {
    this.response;
    const files = await this.fileRepository.find(filter);
    let csv = 'Id,Name';
    files.map(x => {
      csv += `\n${x.Id},${x.Value}`;
    });

    // Manipulate response header
    this.response.set(
      'Content-Disposition',
      'attachment; filename="export.csv',
    );

    return csv;
  }
}

The above code assumes a File model with 2 columns: Id and Value.

Content-Disposition: attachment is usually enough to encourage a web browser to download the file.

Source - https://github.com/loopbackio/loopback-next/issues/4624

user3170450
  • 375
  • 3
  • 20