0

I have no idea how to do the following :

I have this route : "localhost:3000/t-clients/{id}/t-consents"

What it does : Storing the path for an image which should also be uploaded to the path. The table in the database looks like this :

Tables

So, on a client's id, I want to upload a picture on the server side. I have a controller which uploads a picture and one which does the route shown above. What I want to do is to call the controller which uploads the file in my controller which handles the route. I don't have any idea how to do so.

Here are my two controllers I've talked about :

import {inject} from '@loopback/context';
import {
  post,
  Request,
  requestBody,
  Response,
  RestBindings,
} from '@loopback/rest';
import {FILE_UPLOAD_SERVICE} from '../keys';
import {FileUploadHandler} from '../types';

/**
 * A controller to handle file uploads using multipart/form-data media type
 */
export class FileUploadController {
  /**
   * Constructor
   * @param handler - Inject an express request handler to deal with the request
   */
  constructor(
    @inject(FILE_UPLOAD_SERVICE) private handler: FileUploadHandler,
  ) {}
  @post('/file-upload', {
    responses: {
      200: {
        content: {
          'application/json': {
            schema: {
              type: 'object',
            },
          },
        },
        description: 'Files and fields',
      },
    },
  })
  async fileUpload(
    @requestBody({
      description: 'multipart/form-data for files/fields',
      required: true,
      content: {
        'multipart/form-data': {
          // Skip body parsing
          'x-parser': 'stream',
          schema: {
            type: 'object',
            properties: {
              file: {type: 'string', format: 'binary'},
            },
          },
        },
      },
    })
    request: Request,
    @inject(RestBindings.Http.RESPONSE) response: Response,
  ): Promise<object> {
    return new Promise<object>((resolve, reject) => {
      this.handler(request, response, (err: any) => {
        if (err) {
          reject(err);
        } else {
          resolve(FileUploadController.getFilesAndFields(request));
        }
      });
    });
  }

  /**
   * Get files and fields for the request
   * @param request - Http request
   */
  private static getFilesAndFields(request: Request) {
    const uploadedFiles = request.files;

    const mapper = (f: globalThis.Express.Multer.File) => ({
      fieldname: f.fieldname,
      originalname: f.originalname,
      encoding: f.encoding,
      mimetype: f.mimetype,
      size: f.size,
    });

    let files: object[] = [];
    //If only 1 file
    if (Array.isArray(uploadedFiles)) {
      files = uploadedFiles.map(mapper);
    } else {
      //if more than 1
      for (const filename in uploadedFiles) {
        files.push(...uploadedFiles[filename].map(mapper));
      }
    }
    return {files, fields: request.body};
  }
}

The other one

import {
  Count,
  CountSchema,
  Filter,
  repository,
  Where,
} from '@loopback/repository';
import {
  del,
  get,
  getModelSchemaRef,
  getWhereSchemaFor,
  param,
  patch,
  post,
  requestBody,
} from '@loopback/rest';
import {TClient, TConsent} from '../models';
import {TClientRepository} from '../repositories';

export class TClientTConsentController {
  constructor(
    @repository(TClientRepository)
    protected tClientRepository: TClientRepository,
  ) {}

  @get('/t-clients/{id}/t-consents', {
    responses: {
      '200': {
        description: 'Array of TClient has many TConsent',
        content: {
          'application/json': {
            schema: {type: 'array', items: getModelSchemaRef(TConsent)},
          },
        },
      },
    },
  })
  async find(
    @param.path.number('id') id: number,
    @param.query.object('filter') filter?: Filter<TConsent>,
  ): Promise<TConsent[]> {
    return this.tClientRepository.clicon(id).find(filter);
  }

  @post('/t-clients/{id}/t-consents', {
    responses: {
      '200': {
        description: 'TClient model instance',
        content: {'application/json': {schema: getModelSchemaRef(TConsent)}},
      },
    },
  })
  async create(
    @param.path.number('id') id: typeof TClient.prototype.idClient,
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(TConsent, {
            title: 'NewTConsentInTClient',
            exclude: ['idConsent', 'fkClient'],
            //optional: ['fkClient']
          }),
        },
      },
    })
    tConsent: Omit<TConsent, 'idConsent'>,
  ): Promise<TConsent> {
    return this.tClientRepository.clicon(id).create(tConsent);
  }

  @patch('/t-clients/{id}/t-consents', {
    responses: {
      '200': {
        description: 'TClient.TConsent PATCH success count',
        content: {'application/json': {schema: CountSchema}},
      },
    },
  })
  async patch(
    @param.path.number('id') id: number,
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(TConsent, {partial: true}),
        },
      },
    })
    tConsent: Partial<TConsent>,
    @param.query.object('where', getWhereSchemaFor(TConsent))
    where?: Where<TConsent>,
  ): Promise<Count> {
    return this.tClientRepository.clicon(id).patch(tConsent, where);
  }

  @del('/t-clients/{id}/t-consents', {
    responses: {
      '200': {
        description: 'TClient.TConsent DELETE success count',
        content: {'application/json': {schema: CountSchema}},
      },
    },
  })
  async delete(
    @param.path.number('id') id: number,
    @param.query.object('where', getWhereSchemaFor(TConsent))
    where?: Where<TConsent>,
  ): Promise<Count> {
    return this.tClientRepository.clicon(id).delete(where);
  }
}

So my goal is to upload the file to the route, the route receives a message with file and maybe some text like name of the file, and the controller stores the picture and sets the "conPath" to the file path in the server directory.

Thanks for reading. I'm available for any details.

Pouissante
  • 56
  • 1
  • 5
  • 25

0 Answers0