AckerApple / angular-file

Angular components for user file select, drop, and more
http://ackerapple.github.io/angular-file/
MIT License
128 stars 40 forks source link

Using with mutler-s3 #10

Closed joncorrin closed 7 years ago

joncorrin commented 7 years ago

Hi,

Thanks for forking this library, I was having so many issues with it.

I'm having trouble linking this up with multer-s3. This is probably me so bare with me.

I have an Angular/Node application that uses the ngfDirective to make calls to the backend where multer-s3 uploads the files to s3. Here is my current layout. Here is the error I am receiving:

Error: Unexpected field at makeError (/Users/XXX/Desktop/workspace/XXXX/node_modules/multer/lib/make-error.js:12:13)

My component.html file

   <div mat-dialog-title style="text-align: center">
      <!--<h6 *ngIf="filesUploaded" style="margin-bottom: 10px;">Click Create Item Below To List Item</h6>-->
      <h6 *ngIf="!filesUploaded" style="margin-bottom: 10px;">Click Camera to Add Photo For Sale or Rent</h6>
      <!--<h6 *ngIf="!filesUploaded" style="margin-bottom: 10px;">Add Another</h6>-->
    </div>
    <div mat-dialog-content style="text-align: center">
      <!--<div *ngFor="let item of uploader.queue">-->
        <!--<figure class="image-preview" style="margin: 0 auto;" *ngIf="!uploaderLoading">-->
          <!--<img class="is-64x64" src="" imgPreview [image]="item?._file" style="border-radius: 2%;">-->
        <!--</figure>-->
        <!--<p *ngIf="!uploaderLoading">{{ item?.file?.name }}</p>-->
      <!--</div>-->
      <mat-progress-bar mode="indeterminate" *ngIf="uploaderLoading" style="margin: 0 auto"></mat-progress-bar>
      <label for="file-input"><mat-icon *ngIf="!uploaderLoading" style="margin-bottom: 20px;">photo_camera</mat-icon></label>
      <ngfUploader
        [(ref)]     = "uploader"
        [options]   = "{url: devUrl,
                        itemAlias: 'photos'}"
        (save)      = "{}"
        (catch)     = "{}"
      ></ngfUploader>
      <input
        type="file"
        multiple
        class="file-input" 
        id="file-input"
        name="photo"
        accept="image/*"
        ngf
        style="display: none"
        (filesChange)="manualFormDataUploadFiles($event)"
      />
      <!--<input  type="file" name="photo" ngf [(files)]="files" [(file)]="file" multiple style="display: none">-->
    </div>
    <div mat-dialog-actions>
      <!--<button mat-raised-button color="primary" (click)="uploadFiles(files)" *ngIf="!filesUploaded && files" style="margin: 0 auto;" tabindex="2"><p class="p2">UPLOAD</p></button>-->
      <button mat-raised-button color="primary" (click)="sendByModel(file)" *ngIf="!filesUploaded && file" style="margin: 0 auto;" tabindex="2"><p class="p2">UPLOAD</p></button>

      <button mat-raised-button *ngIf="filesUploaded" color="primary" (click)="addItem()"><p class="p2">CREATE ITEM</p></button>
      <button mat-button (click)="onClose()"><p class="p2">CLOSE</p></button>
    </div>

My .ts file

export class UploaderDialogComponent implements OnInit {
  devUrl = 'XXX';
  url = 'XXX';
  filesUploaded = false;
  public uploader: ngfUploader;

  constructor(
    private http: Http,
    private userS: UserService,
    private contactS: ContactService,
    private router: Router,
    private uis: UiService,
    private itemS: ItemService,
    public dialogRef: MatDialogRef<UploaderDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any) { }

  ngOnInit() {
  }
// I tried all three
  uploadFiles(files: File[]):Promise<Response>{
    const uploader:FileUploader = this.uploader;

    const formData: FormData = uploader.getFormData(files);
    console.log(formData);

    const config = new Request({
      url: this.devUrl,
      method: 'POST',
      body: formData
    });

    return this.postRequest(config)
  }

  postRequest(config: Request):Promise<Response>{
    return this.http.request(config)
      .toPromise()
      .then( response => {
        alert('Upload Complete');
        return response;
      })
      .catch(e => this.uis.onFlash('ERROR POSTING IMAGE: ' + e.toString(), 'ERROR'));
  }

  sendByModel(file: File):Promise<Response>{
    const formData:FormData = this.uploader.getFormData( [file] );

    const config = new Request({
      url: this.devUrl,
      method:'POST',
      body: formData
    });
    return this.postRequest(config)
  }

  manualFormDataUploadFiles(files:File[]):Promise<Response>{
    const formData:FormData = new FormData();

    for (let file of files) {
      formData.append('file', file, file.name);
    }

    const config = new Request({
      url: this.devUrl,
      method:'POST',
      body:formData
    });

    return this.postRequest(config)
  }
}

And here is the backend code that raises the error

var express = require('express');
var router = express.Router();
var aws = require('aws-sdk');
var fs = require('fs');
var path = require('path');
var path3 = path.join(__dirname, "../config/config-aws.json");
var pdf = require('pdfkit');
var multer = require('multer');
var multerS3 = require('multer-s3');

aws.config.loadFromPath(path3);
var s3 = new aws.S3();
var fileName = '';
var uploadM = multer({
  storage: multerS3({
    s3: s3,
    bucket: 'XXX',
    acl: 'public-read',
    metadata: function (req, file, cb) {
      cb(null, {fieldName: file.fieldname});
    },
    key: function (req, file, cb) {
      fileName = Date.now().toString() + "-" + (Math.round(Math.random() * 100000)).toString() + '-' + file.originalname;
      cb(null, fileName)
    }
  })
});

router.post('/server/upload', uploadM.array('photos', 3), function(req,res) {
    if (res.error) {
      return res.status(400).json({
        message: "Error",
        error: res.error
      });
    }
    return res.status(200).send(fileName);

});

module.exports = router;

I've played around for a bit trying different methods and using itemAlias. With the outdated library I had it setup and working and I assumed I'd need to do some work to get multer-s3 up and running again.

Thanks, again for helping and creating this, it was much needed!

AckerApple commented 7 years ago

Hey there good guy! Thanks for the report

All my implementations of this library put files on Amazon S3. So it works.

The new forked intent of this library, is only to support selecting files. No future support of how files are transmitted nor how the servers work, will be given. Sorry guy, I got no help for you

Please close issue