Check out these project files that you are welcome to use. If you have any questions, feel free to ask. I believe the comments provided should be sufficient for understanding:
ANGULAR SERVICE
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
// Environment is important for the nodeJS API endpoint
import { environment } from '../../../environments/environment';
@Injectable()
export class S3UploadService {
constructor(private http: Http, private session: SessionManagerService) { }
/**
* Retrieves a signed request from AWS
* @param file The file to be uploaded
*/
getSignedRequest(file: File): Observable<{ signedRequest: string, url: string }> {
// Generating a unique name: 8 random characters, user ID, timestamp, extension. Ensuring uniqueness.
let name = Math.random().toString(36).substr(2, 8)
+ '-' + Parse.User.current().id + '-'
+ new Date().getTime().toString() + '.'
+ file.name.split('.').pop();
return this.http.get(`${environment.remoteUrl}sign-s3?file-name=${name}&file-type=${file.type.toLowerCase()}`)
.map(data => data.json())
.catch(err => Observable.throw(err));
}
/**
* Sends a file to Amazon for uploading
* @param file The file being uploaded
* @param signedRequest The signed request obtained from getSignedRequest method
* @param url The URL of the file on AWS
*/
uploadFile(file: File, signedRequest: string, url: string): Observable<{ url: string }> {
// No json() function needed here as Amazon does not send json responses.
return this.http.put(signedRequest, file)
.map(data => {
// Removing the signature portion
data.url = data.url.split('?')[0];
return data;
})
.catch(err => Observable.throw(err));
}
}
NODEJS ENDPOINT
// Obtain a signed request from Amazon.
app.get('/sign-s3', function(req, res) {
const s3 = new aws.S3();
const fileName = req.query['file-name'];
const fileType = req.query['file-type'];
const s3Params = {
Bucket: S3_BUCKET,
Key: fileName,
Expires: 60,
ContentType: fileType,
ACL: 'public-read'
};
s3.getSignedUrl('putObject', s3Params, function(err, data) {
if (err) {
console.log('Error occurred : \n' + err);
return res.status(500).send(JSON.stringify({ message: 'Internal Server Error' }));
}
const returnData = {
signedRequest: data,
url: 'https://' + S3_BUCKET + '.s3.amazonaws.com/' + fileName
};
res.write(JSON.stringify(returnData));
res.end();
});
});