Angular6 Rename the File to be Uploaded

12.8k Views Asked by At

I am using Angular6 and NodeJS for my API. MY application is a School Software where I should save Students Images with their Registration Numbers. I am using ng2-file-upload in Angular for File Uploads and Multer in NodeJS, Upload is working perfectly, but I can't understand how to rename the file with the registration number of Student. My url in Angular consists of Student Registration number, I just need to know how to send that Reg. Number to NodeJS and rename the file with Reg. Number


My html File

<input type="file" name="photo" ng2FileSelect [uploader]="uploader" />

<button type="button" class="btn btn-success btn-s" 
  (click)="uploader.uploadAll()" 
  [disabled]="!uploader.getNotUploadedItems().length" >
      Upload an Image
</button>

My .ts file

public uploader: FileUploader = new FileUploader({url: URL, itemAlias: 'file'});
  ngOnInit() {
    this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; };
    this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
         console.log('ImageUpload:uploaded:', item, status, response);
         alert('File uploaded successfully');
     };
  }

My NodeJS Multer Upload:

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, 'E:/school')
    },
    filename: function (req, file, cb) {
      cb(null, Date.now() + '-' + file.originalname);
    }
  });

  var upload = multer({ storage: storage });

  router.post('/upload', upload.single('file'), (req, res) => {
      if (!req.file) {
        console.log("No file received");
        return res.send({
          success: false
        });

      } else {
        console.log('file received');
        return res.send({
          success: true
        })
      }
  });

Thanks in Advance. Any help will be Appreciated.

3

There are 3 best solutions below

5
On

You should be able to watch the onFileSelected event and get file[0] (if you are single file upload). And set the file[0].name before uploading.

0
On

You can edit the name before posting the formData to the backend. Give the file name (or get from a form) and get the file extension from the file to upload. Then append to formData before posting to the backend.

Reference: https://stackoverflow.com/a/55178342 and https://youtu.be/v67NunIp5w8

  let fileToUpload = <File>files[0];
  let fileName:string = 'test-name' //get name from form for example
  let fileExtension:string = fileToUpload.name.split('?')[0].split('.').pop();

  const formData = new FormData();
  formData.append('file', fileToUpload, fileName+'.'+fileExtension);

  this.http.post(environment.backendApiUrl+'/api/upload', formData, {reportProgress: true, observe: 'events'})
    .subscribe(event => {
      if(event.type === HttpEventType.UploadProgress) {
        this.progress = Math.round(100 * event.loaded / event.total);
      } else if (event.type === HttpEventType.Response) {
        this.message = 'Upload success.';
        this.onUploadFinished.emit(event.body);
      }
    });
0
On

Be careful: This solution should work however this code is ugly and probably not the best way to do what you want. But it's just to show you how you can rename your file in the front-end side.

Important: I will assume you are uploading a single file because we will use the first item of the uploader.queue for this example.

First, you can add an input type text in your HTML file just below your input file :


<input *ngIf="uploader.queue.length" type="text" name="file" [value]="uploader.queue[0].file.name"
       (change)="renameFile($event.target.value)"/>

This input will be showed when you will upload a file. The (change) will trigger the renameFile func in your component with the current input value.

Then update your TS component by adding the renameFile method :

renameFile(name: string): void {
    // fetching the item uploaded
    const oldFileItem: FileItem = this.uploader.queue[0];
    // re-instanciating a new file based on the old file by changing the name property
    const newFile: File = new File([this.uploader.queue[0]._file], name, {type: oldFileItem.file.type});
    // uploader.queue is taking FileItem objects, instanciating a new FileItem
    const newFileItem = new FileItem(this.uploader, newFile, this.opts);

    // replacing the old one by the new file updated
    this.uploader.queue[0] = newFileItem;
  }

Finally, you can have a look to the file property in your console.log inside the onCompleteItem function, the file has been updated.