#is there anybody who can help me in how to upload image files in nestjs to a postgresql database

149 messages · Page 1 of 1 (latest)

trim leaf
#

hi i am aijaz i am working on a project using nestjs and postgresql , i am doing the backend part , while submitting a form with some image data i faced this issue i tried to resolve it on my own but could not find any good resource also i am doing this for the first time , help will be appreciated

placid ether
# trim leaf hi i am aijaz i am working on a project using nestjs and postgresql , i am doin...

i would suggest multer, the guide can be found here
edit: forgot the url srry 😅
https://docs.nestjs.com/techniques/file-upload

placid ether
trim leaf
#

but i dont know how to do that

#

i am totally beginner

placid ether
trim leaf
#

if i share with u the link of that folder , can u make that post api work for uploading images as well

#

if u have a little time please , i am stuck on this part since past 3 4 days

placid ether
#

what part are you stuck on?

trim leaf
#

this image upload part through forms

placid ether
trim leaf
#

no the problem is with backend

placid ether
trim leaf
#

yes that's what i was asking , i ll share with you the folder which consists of the whole code

#

what you have to do is make that post api work

placid ether
trim leaf
#

it has multiple files like controller part multerconfig and service part if you can help me with that .

#

please ill share the link of google drive you just have do some little changes

placid ether
#

just post your code as text here

trim leaf
#

okay

placid ether
#

we are here to help not do do the work for you

trim leaf
#

no i did not mean that

dense snowBOT
#

Please format your question with Markdown formatting.
It leads to better readability and an easier time to spot problems.
For code blocks, you can wrap your block with three back ticks before and after the block, and after the first three back ticks you can add a language (like ts) to add syntax highlighting.
e.g.

```ts
@Injectable()
export class MySuperAwesomeService {
constructor(@Inject('InjectionToken') private readonly dep: SomeDependency) {}

getRandomNumber(): number {
return Math.round(Math.random() * 1000);
}
}
```

Becomes

@Injectable()
export class MySuperAwesomeService {
  constructor(@Inject('InjectionToken') private readonly dep: SomeDependency) {}

  getRandomNumber(): number {
    return Math.round(Math.random() * 1000);
  }
}
trim leaf
#
import { diskStorage } from 'multer';
import { extname } from 'path';

export const multerConfig = {
  dest: './uploads', // The destination folder where uploaded files will be stored
  storage: diskStorage({
    destination: (req, file, cb) => {
      cb(null, './uploads');
    },
    filename: (req, file, cb) => {
      // Rename the uploaded file to avoid name conflicts
      const randomName = Array(32)
        .fill(null)
        .map(() => Math.round(Math.random() * 16).toString(16))
        .join('');
      cb(null, `${randomName}${extname(file.originalname)}`);
    },
  }),
};
#
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ImageEntity } from './entities/image.entity';
import { ImageRepository } from './repo/image.repository';

@Injectable()
export class ImageService {
  constructor(
    @InjectRepository(ImageEntity)
    private readonly imageRepository: ImageRepository) {}

  async createImage(imageData: ImageEntity): Promise<ImageEntity> {
    const newImage = this.imageRepository.create(imageData);
    return await this.imageRepository.save(newImage);
  }
}```
#
import { Controller, 
  Post,
   Body,
    UploadedFile,
  UseInterceptors,
 } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ImageService } from './image.service';
import { ImageEntity } from './entities/image.entity';

@Controller('images')
export class ImageController {
  constructor(private readonly imageService: ImageService) {}

  @Post()
  @UseInterceptors(FileInterceptor('palmImage'))
  async uploadImage(
    @Body() imageInfo: ImageEntity,
    @UploadedFile() palmImage: Express.Multer.File,
    @UploadedFile() photoImage: Express.Multer.File,
  ): Promise<ImageEntity> {
    imageInfo.palmImagePath = palmImage.path;
    imageInfo.photoImagePath = photoImage.path;

    return this.imageService.createImage(imageInfo);
  }
}```
#

do you need anything else

#
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class ImageEntity {
  @PrimaryGeneratedColumn()
  id: number;
  @Column()
  name:string;

  @Column()
  address:string;

  @Column()
  palmImagePath: string;

  @Column()
  photoImagePath: string;
}
#
import { Module } from '@nestjs/common';
import { ImageService } from './image.service';
import { ImageController } from './image.controller';
import { ImageEntity } from './entities/image.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
import { multerConfig } from './multer.config';
import {MulterModule} from '@nestjs/platform-express'

@Module({
  imports:[TypeOrmModule.forFeature([ImageEntity]),
  MulterModule.register(multerConfig),],
  controllers: [ImageController],
  providers: [ImageService]
})
export class UserModule {}```
placid ether
trim leaf
#

this is the whole file structure for this post api , do let me know if you need anything else

placid ether
trim leaf
#

yes

#

im trying this for the first time

#

actually i have to implement the same logic in my project after this

placid ether
#

i would suggest looking at
https://docs.nestjs.com/techniques/file-upload#multiple-files
or
https://docs.nestjs.com/techniques/file-upload#array-of-files

there are special settings for when you want to use multiple files

trim leaf
#

i have already read this documentation it is not helping me , i checked some other documentations as well but i am unable to achieve this

placid ether
#

multer needs to know if you are uploding multiple or 1, double 1 is not going to work

trim leaf
#

let's do this stepwise , is this controller and service part correct?

placid ether
# trim leaf let's do this stepwise , is this controller and service part correct?

controller is already where it goes wrong
looking at your code you have what you named
palmImage and photoImage
i would suggest to start with a modified version of the example provided by nest
for now lets not bring your services or body in the mix (yet), step by step


@Post('images')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'palmImage', maxCount: 1 },
  { name: 'photoImage', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { palmImage?: Express.Multer.File[], photoImage?: Express.Multer.File[] }) {
  //log your files and check your results
}
#

let me know how it goes
i need to do, cough something... 🚽

trim leaf
#

okay

#

but please help me with the whole when you will be free

placid ether
#

In the meantime let me know if you get anything logged and what

trim leaf
#

Error: ENOENT: no such file or directory, open 'C:\Users\adm\Desktop\fileUpload\image-upload\uploads\b8675751e734f1021896aa2e83668ccc10.jpg'
[Nest] 17840 - 02/08/2023, 2:15:51 am ERROR [ExceptionsHandler] ENOENT: no such file or directory, open 'C:\Users\adm\Desktop\fileUpload\image-upload\uploads\b10d863e106e81160556f73bf0810ed7ff1.jpg'

placid ether
trim leaf
#

i think this from the multer file which i have i guess

#

if you can check the whole file it will be easy for u and for me also please

#

i am ready to share the google drive link

placid ether
#

i'm not going to do that, not spoon feeding here

trim leaf
#

i have already setup everything

placid ether
#

leave anything that ins't required to run this out of the picture

trim leaf
#

you just have to check the files where i am doing wrong

placid ether
#

no services or anything, make sure only the controller run

trim leaf
#

😫 ok

placid ether
#

you dont have to delete them, only comment them out

trim leaf
#

okk

#

the controller file is not showing any error

placid ether
#

anything related to that end point should't run at this point of time, disable services, pipes and anything else that relates to the end point
any thing that does not relate should be fine

placid ether
trim leaf
#

[Nest] 13080 - 02/08/2023, 2:44:03 am LOG [RouterExplorer] Mapped {/images/add, POST} route +6ms
[Nest] 13080 - 02/08/2023, 2:44:03 am LOG [NestApplication] Nest application successfully started +12ms

placid ether
trim leaf
#

last time i tried to enter the image file through postman that's why that error was thrown

placid ether
#

that is why we need to do this step by step

@Post('images')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'palmImage', maxCount: 1 },
  { name: 'photoImage', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { palmImage?: Express.Multer.File[], photoImage?: Express.Multer.File[] }) {
  //log the files here, and tell what they are
}
trim leaf
#

okay , what is the next step then

placid ether
#

tell me what is getting logged, that's next

trim leaf
#
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] AppModule dependencies initialized +56ms
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] TypeOrmModule dependencies initialized +1ms   
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] ConfigHostModule dependencies initialized +1ms
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] ConfigModule dependencies initialized +1ms    
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] ConfigModule dependencies initialized +1ms    
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +400ms
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] TypeOrmModule dependencies initialized +2ms
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [InstanceLoader] UserModule dependencies initialized +4ms
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [RoutesResolver] ImageController {/images}: +51ms
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [RouterExplorer] Mapped {/images/add, POST} route +8ms
[Nest] 10336  - 02/08/2023, 2:50:37 am     LOG [NestApplication] Nest application successfully started +12ms```
placid ether
#

i dont need the full server log, only the part of the end point that you run
need to confirm the code i send runs

trim leaf
#

yes its running properly

placid ether
#

i got that, but what does the log say?

trim leaf
#

about which log are you talking , this is the whole list of logs that i got in the terminal

#

sorry i am noob

placid ether
#

these logs

#

i dont care about the server log of the server starting up

#

add a logger and tell what "files" tell

trim leaf
#

i dont know how to do the same

placid ether
#

sorry i cant try to help you anymore
i think it is to much for me
getting slightly frustrated at this point, and think i need to quit it, hope somebody else can help you
😔

trim leaf
#

im trying to add these logs and check the results , ill let you know once i am done

#
export class ImageController {
  constructor(private readonly imageService: ImageService) {}

  @Post('add')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'palmImage', maxCount: 1 },
  { name: 'photoImage', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { palmImage?: Express.Multer.File[], photoImage?: Express.Multer.File[] }) {
  //log your files and check your results
  const logger = new CustomLogger('uploadFile');
if (files.palmImage) {
  logger.info('Palm image uploaded:');
}
if (files.photoImage) {
  logger.info('Photo image uploaded:');
}
}```
#
info: Photo image uploaded:```
#

this is how i modified this file an d the result

#

this is the log i got when i tried to hit post api on postman which consisted of two image files

cold pivot
trim leaf
#

no , actually started building it from controller

#

this is the controller part above

#

if you anyone can help me in building this api for uploading images to the database that will be really appreciable

cold pivot
#

What's the actual issue here? With what you have above, what do you expect to happen vs what is actually happening?

#

Also, I would highly suggest against saving raw images in the database. The data type doesn't lend itself well to it. Save them on the file system (or some other file store likeS3) and save the paths in the database

trim leaf
#

actually i was trying to create a post api for form submission which consisted of few text columns like name email and address and two image columns photo image and palmImage .

#

so what happened i wasnt able to create the same , i am new to this nestjs , i could not find any resources which would have explained that complete image upload to the database .

#

luckily i found this discord server somehow , and i am here with the same problem

cold pivot
#

i am new to this nestjs
Yeah, I've seen you say this a lot, you don't need to keep saying it
i could not find any resources which would have explained that complete image upload to the database .
Because absolutely no one recomends you actually upload the file to the database. You save it to the file system or a file storage and save the path to the database

You also still haven't said really what the issue is, just what you're wanting to do and that you can't figure it out, but not really what is stumping you, so it's hard to know how to help

trim leaf
#

like logic in the controller , service and multer config file

trim leaf
cold pivot
#

Somethingroughly like

@Controller('file')
export class UploadController {
  @Post('upload')
  @UseInterceptor(FilesInterceptor([
    { name: 'photo', maxCount: 1},
    { name: 'palm', maxCount: 1 },
  ])
  uploadFiles(@UploadedFiles() files: Express.Multer.File[], @Body() body: OtherFields) {
    doLogic()
  }
}

This is the basic structure of what you would need

trim leaf
#

can you also help me in the service and multerconfig building

cold pivot
#

What about it?

trim leaf
#

i had tried it before in the 4 5 hours back , i have shared the code snippet also above

cold pivot
trim leaf
#

i am having problem in the building the logic like i dont have any idea what to do next

#

do you understand hindi ?

cold pivot
#

What do you know to do so far? Where are you stuck?

cold pivot
trim leaf
#

logic for uploading image is totally different

#

that

cold pivot
#

You have the logic for uploading imahes already

trim leaf
#

where ?

cold pivot
#

That's what the FilesInterceptor is for

#

That's what parses the image on your server from the multipart request

trim leaf
#

what is the function of multerconfig then ?

cold pivot
#

From there, you take the information from multer and act on it accordingly

cold pivot
trim leaf
#

okay ill will try

#
export class ImageService {
  constructor(
    @InjectRepository(ImageEntity)
    private readonly imageRepository: ImageRepository) {}

  async createImage(imageData: ImageEntity): Promise<ImageEntity> {
    const newImage = this.imageRepository.create(imageData);
    return await this.imageRepository.save(newImage);
  }
}```
#

is this service part correct based on the above controller

cold pivot
#

For the third time please do not save the image in the database. Save it to the server's filesystem or to a file store like S3 or other cloud provider

trim leaf
#

how do the same

#

i am sorry for irritating you , please dont mind i dont have any idea how to achieve the same

cold pivot
#

For the flesystem there's multer's disk storage plugin, or just taking the buffer from memory and writiing to the disk using the fs module. For S3, check their SDK and docs

cold pivot
trim leaf
#

i am really very sorry , can you suggest me some good resources where ill get to know about the image upload part , i really want to understand the its flow

trim leaf
#

thank you im trying to do this on my own from here onwards

placid ether
# trim leaf <@211445675701829632> pl check this

close to what i had in mind, suppose this works
would help if i knew what files it self would log, but i know the process is going well and that is the most important part

now, are the images actually saved in the directory? can you check that?

trim leaf
#

no because the service part is commented out

placid ether
#

try to fix that that and let me know if you run into any problems
see how far you get your self

trim leaf
#

ill try that

#

can you give me an idea what to do in the service file

placid ether
trim leaf
#
  imports: [
    ConfigModule.forRoot({ isGlobal:true , envFilePath:['.local.env']}),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get('DATABASE_HOST'),
        port: configService.get<number>('DATABASE_PORT'),
        username: configService.get('DATABASE_USERNAME'),
        password: configService.get('DATABASE_PASSWORD'),
        synchronize: configService.get<boolean>('DATABASE_SYNC'),
        //logging: configService.get<boolean>('DATABASE_LOGGING'),
        database: configService.get('DATABASE_NAME'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
        logging:true,
      
      }),
    }),

    UserModule],
  controllers: [],
  providers: [],
})
export class AppModule {}```
placid ether
#

yeah your app.module does not have access to your image.module that has the multer.module
fix that first

trim leaf
#

user module is the same image module

#

still i updated it to image module

#
  imports: [
    ConfigModule.forRoot({ isGlobal:true , envFilePath:['.local.env']}),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get('DATABASE_HOST'),
        port: configService.get<number>('DATABASE_PORT'),
        username: configService.get('DATABASE_USERNAME'),
        password: configService.get('DATABASE_PASSWORD'),
        synchronize: configService.get<boolean>('DATABASE_SYNC'),
        //logging: configService.get<boolean>('DATABASE_LOGGING'),
        database: configService.get('DATABASE_NAME'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
        logging:true,
      
      }),
    }),
    ImageModule],
  controllers: [],
  providers: [],
})
export class AppModule {}```
placid ether
#

will be back later

trim leaf
#

okey

placid ether
#

sorry kinda forgot about this

#

anyways at this point, the uploading should work
multer is the one resposible for uploading, not the services

cold pivot
#

The only "exception" would be if the storage: memory (default) is used, and they need to use the filesystem module (fs) to write the buffer to diisk, but that should be straightforward enough

placid ether