Q:

Web Application with Angular 4: how to return a public link with Amazon S3?

I'm developing a web application with Angular 4 using TypeScript language.
The backend of this application is based on AWS.
Unfortunately I don't have a great knowledge of TypeScript (JavaScript) methods to call up procedures that interacting with AWS services, but what I have to do is very simple.
The question is: if I load a file on a Amazon S3 Bucket (an image), 
how do I get the link (like as string) that let me use it to show the image on the web page? 
I would like to create an internal TypeScript method for my application, 
without make public the link using the command on S3. 
This method must have a reference to the bucket S3 (folder name and file name) and must return a public link as a string accessible to anyone. Anyone who knows how to do this thing can tell me?

A:

Here are files from my project that you can use. If you need any explanation, feel free to ask, but I guess that with comments only, you could understand it : 
ANGULAR SERVICE 
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
// environment useful for the nodeJS API endpoint
import { environment } from '../../../environments/environment';

@Injectable()
export class S3UploadService {

  constructor(private http: Http, private session: SessionManagerService) { }

  /**
   * Gets a signed request from AWS
   * @param file The file to upload
   */
  getSignedRequest(file: File): Observable<{ signedRequest: string, url: string }> {
    // Randomly generated name : 8 random, user ID, timestamp, extension. Should ensure 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));
  }

  /**
   * Uploads a file on Amazon
   * @param file The file to upload
   * @param signedRequest The signed request returned by the getSignedRequest method
   * @param url The URL of the file on the AWS
   */
  uploadFile(file: File, signedRequest: string, url: string): Observable<{ url: string }> {
    // WARNING : No json() function here, Amazon doesn't send json responses.
    return this.http.put(signedRequest, file)
      .map(data => {
        // get rid of the signature
        data.url = data.url.split('?')[0];
        return data;
      })
      .catch(err => Observable.throw(err));
  }
}

NODEJS ENDPOINT
// Gets 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 occured : \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();
  });
});

