How to access image from uploaded on nestjs server

Viewed 5856

I have a nestjs server and I have uploaded the images but when I try to access to those images they are a bunch of stuff that cant be interpreted as an image.(I also tried converting them to blob which then I converted to objectURL and then set it as src for img tag but that didnt work either).Upload code:

    @Post('upload')
    @UseInterceptors(FileInterceptor('file',{
        storage: diskStorage({
          destination: './uploads',
          filename: editFileName,
        }),
        fileFilter: imageFileFilter,
      }))
    uploadFile(@UploadedFile() file){
        console.log(file);
        file.filename = file.originalname;
        const response = {
            originalname: file.originalname,
            filename: file.filename,
        }
        return response;
    }

The above upload code perfectly saves the image as index-53a2.jpg in my uploads folder. Now trying to get the image using get req by:

@Get()
display(@Res() res){
    res.sendFile('index-53a2.jpg',{ root: './uploads' })
}

logging response for this it gives some string of unreadable(probably encoded) stuff.

code I used for testing:

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
    <script>
      $(function () {

        $('#abc').on('submit', function (e) {

          e.preventDefault();

          $.ajax({
            url: 'http:/localhost:3000/student/upload',
            method:'POST',
            data: new FormData(this),
            contentType: false,
            cache:false,
            processData:false,
            success: function (data) {
              console.log(data);
              // location.reload();
            }
          });

        });

      });

      function fun(){
        $.ajax({
            url: 'http://localhost:3000/student',
            success: function(data){
                console.log('s',data);
                let blob = new Blob([data]);
                var objectURL = URL.createObjectURL(blob);
                document.getElementById('img').src = objectURL;
            },
            error: function(data){
                console.log('e',data);
            }
        })
      }
    </script>
  </head>
  <body>
    <img alt="Image" id="img">
    <form enctype= "multipart/form-data" id="abc">
      <input type="file" name="file" required accept="image/*"><br>
      <input name="submit" type="submit" value="Submit">
    </form>
    <button onclick="fun()">Button</button>
  </body>
</html>

Also this html code is just for testing, my main purpose is to use this server so that I can take student image and data(contains basic details like name, phone, etc.) from angular and save it on mongoDB. Also I dont have any idea how to send my image from angular to nestjs and how to save it(and where to save it on MongoDB or Nestjs server and how)

Any help would be greatly appreciated!!! Thanks in advance.

2 Answers

To access to your files with NestJs you need to define your static assets directory name in the main.ts using the .useStaticAssets method on your app

app.useStaticAssets(join(__dirname, '..', 'public'), {
    index: false,
    prefix: '/public',
});

I found solution to this. So what we have to do is basically append all our data in formData and send it in the request from angular.

let formData = new FormData();
formData.append('image',this.image);

Now this image attribute is taken from the function triggered by the onchange on the input tag that takes image as input.

onChange(event){
   this.image = event.target.files[0];
}

Now we send it to backend from our service.

sendReq(formData){
   this.http.post('localhost:3000/your_route',formData);
}

Now while accessing it from the Nestjs server we use FileInterceptor.

import { Controller, Get, Post, Res, UploadedFile, UseInterceptors, Body } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { editFileName, imageFileFilter } from './funcs';
import { diskStorage } from 'multer';



@Post('your_route')
@UseInterceptors(FileInterceptor('image',{
        storage: diskStorage({
          destination: './uploads',
          filename: editFileName,
        }),
        fileFilter: imageFileFilter,
      }))
    async func(@UploadedFile() file, @Body() body){
        try{
            body.image = file.filename;
            body.view = false;
            let res = await this.yourService.yourFunc(body);
            return {
                'success': true,
                'data': res
            }
        }
        catch(err){
            console.log(err);
            return {
                'success': false,
                'data': err
            }
        }
    }

const imageFileFilter = (req, file, callback) => {
    if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
      return callback(new Error('Only image files are allowed!'), false);
    }
    callback(null, true);
  };

 const editFileName = (req, file, callback) => {
    const name = file.originalname.split('.')[0];
    const fileExtName = '.'+file.originalname.split('.')[1];
    const randomName = Array(4)
      .fill(null)
      .map(() => Math.round(Math.random() * 16).toString(16))
      .join('');
    callback(null, `${name}-${randomName}${fileExtName}`);
  };

So this way we get a uploads folder in our root directory and image uploaded to our server gets saved here. To save the image the name I have user here is the name of the file being uploaded + '-' + a sequence of random char and int of length 4(Here you can have logic of your own).

Related