I'VE FOUND THE SOLUTION!!!
I'm writing the backend in Nest.Js / PostgreSQL using Sequelize.js. I want to upload form-data (field + file); and save: file to static/uploads, field with file URL to the DB. I've managed to write the code for file upload with Multer.js, but I'm struggling with sending data (not a file actually) to the DB. Please, advise how to write the controller and service.
app.module.ts
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: process.env.PUBLIC_DIR || path.join(__dirname, '../../public'),
serveRoot: '/static',
}),
DatabaseModule,
ConfigModule.forRoot({ isGlobal: true }),
UsersModule,
AuthModule,
PostsModule,
MulterModule.register({
dest: './static/uploads',
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
posts.module.ts
@Module({
imports: [
MulterModule.register({
dest: 'static/uploads',
}),
DatabaseModule,
],
providers: [PostsService, ...postsProviders],
controllers: [PostsController],
exports: [PostsService],
})
export class PostsModule {}
file.entity.ts
@Table
export class File extends Model<File> {
@Column({
type: DataType.STRING,
allowNull: false,
})
name: string;
@Column({
type: DataType.STRING,
allowNull: false,
})
url: string;
@ForeignKey(() => Post)
@Column({
type: DataType.INTEGER,
allowNull: false,
})
postId: number;
@BelongsTo(() => Post)
post: Post;
}
file.dto.ts
export class FileDto {
@IsNotEmpty()
readonly name: string;
@IsNotEmpty()
readonly url: string;
}
posts.controller.ts
@Post('images')
@UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
destination: process.env.PUBLIC_DIR || path.join(__dirname, '../../../public'),
filename: editFileName,
}),
fileFilter: imageFileFilter,
}),
)
async uploadedFile(@UploadedFile() file, @Request() req, @Body() body ): Promise<File> {
return await this.postService.createFile(req.post.id, file, body.name);
}
posts.service.ts
import { Injectable, Inject } from '@nestjs/common';
import { Post } from './post.entity';
import { PostDto } from './dto/post.dto';
import { User } from '../users/user.entity';
import { POST_REPOSITORY } from '../../core/constants';
import { FILE_REPOSITORY } from '../../core/constants';
@Injectable()
export class PostsService {
constructor(
@Inject(POST_REPOSITORY) private readonly postRepository: typeof Post,
@Inject(FILE_REPOSITORY) private readonly fileRepository: typeof File,
) { }
async create(post: PostDto, userId): Promise<Post> {
return await this.postRepository.create<Post>({ ...post, userId });
}
async createFile(postId: number, file: any, bodyName ): Promise<File> {
return await this.fileRepository.save({
name: bodyName,
url: `${process.env.URL}/static/${file.filename}`,
postId: postId,
});
}
async findAll(): Promise<Post[]> {
return await this.postRepository.findAll<Post>({
include: [{ model: User, attributes: { exclude: ['password'] } }],
});
}
async findOne(id): Promise<Post> {
return await this.postRepository.findOne({
where: { id },
include: [{ model: User, attributes: { exclude: ['password'] } }],
});
}
async delete(id, userId) {
return await this.postRepository.destroy({ where: { id, userId } });
}
async update(id, data, userId) {
const [numberOfAffectedRows, [updatedPost]] = await this.postRepository.update({ ...data }, { where: { id, userId }, returning: true });
return { numberOfAffectedRows, updatedPost };
}
}
Also, I got an error in posts.service.ts -
Property 'save' does not exist on type '{ new (fileBits: BlobPart[], fileName:
string, options?: FilePropertyBag): File; prototype: File; }'.ts(2339)
Appreciate any help )