1

I am new in Angular2. I would like to have a single class or a configuration file having all my API endpoints (allowing parameters and such in the different routes) that I could inject in all my services. What's the best way to do so in Angular2. I mean, should I define an @Injectable class as you would do when defining a service (and then add it to my services'PROVIDERS).

The problem that I found is when I will deploy my api on a server in the client part I must change all endpoint called in string format so it will be wasted time if I have many endpoints to work with.

in this example I call a service with an endpoint in string format :

getData() {
    return this._http.get('http://localhost:8000/cartography')
      .map(function(res) {
        const jsonArray = res.json();
        const newJsonArr = [];
        for ( let i = 0; i < jsonArray.length; i++) {
          const object = {
            post_name : jsonArray[i].name,
            employment_name : jsonArray[i].employment.name,
            profession_name : jsonArray[i].employment.profession.name,
            family_name : jsonArray[i].employment.profession.family.name
          };
          newJsonArr.push(object);
        }
          return newJsonArr;
      });
  }

so I'm looking for a way to define it as global var in a class or config file. any help please ! thanks .

547n00n
  • 1,356
  • 6
  • 30
  • 55

4 Answers4

9

You can just have a constants file. Its not a special file, we can do it in any file.

url.constants.ts

export const URL1 = "..... " 
export const URL2 = " .... " 

You can then access them anywhere in your code

import { URL1 } from 'url.constants';

or you can put them in a JSON file

Its not straightforward. You can see how it is done here https://hackernoon.com/import-json-into-typescript-8d465beded79

As mentioned in comments, it got easier : https://stackoverflow.com/a/50674344/1195056

Update:

Another advantage of putting constants in typescript file is: we can use functions.

For ex:

export const USER_NOT_FOUND = (user:string)=> `${user} not found ` 

This can be used like

const errorMessage = USER_NOT_FOUND(this.user.name);
Vamshi
  • 9,194
  • 4
  • 38
  • 54
  • Thanks for your help :) – 547n00n Jul 04 '17 at 08:31
  • Importing a JSON file is a lot easier now in TypeScript 2.9+. See [this answer](https://stackoverflow.com/a/50674344/1195056) for how to do that. – krillgar Dec 04 '18 at 13:45
  • say I need to concatenate each API endpoint with "environment.host" from environment.ts file, can I import environment file in url.constant file? URL1 = environment.host + "rest/of/url.." – Sushmit Sagar Dec 24 '18 at 08:19
  • In short yes !. It is a just a typescript file and environment.ts is also another typescript file. – Vamshi Dec 24 '18 at 08:23
0

If the question is really how to handle a different endpoint prefix at deployment than at development time ... then the answer is to use the HTML base tag in your index.html like this:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Acme Product Management</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <pm-root></pm-root>
</body>
</html>

Then you can simply change this base tag before deploying. If you are using Angular CLI, there is even an option for that.

From the CLI docs:

# Sets base tag href to /myUrl/ in your index.html
ng build --base-href /myUrl/
ng build --bh /myUrl/

If you are really looking for more of a configuration file based approach, check this out: https://github.com/angular/angular/issues/9047#issuecomment-224075188

DeborahK
  • 57,520
  • 12
  • 104
  • 129
  • Thanks for your answer, this not what I'm looking for , the problem is how to define a globals variables in a class or config file for the different API Endpoints and inject it on my services so in the deployment all endpoints will be change easily ! – 547n00n Jul 03 '17 at 23:00
  • Did the second suggestion (github link at the bottom) provide what you need regarding a configuration file? – DeborahK Jul 03 '17 at 23:10
0

I am wondering you are looking for something like interceptor or helper. And global variable.

1) You can define global string variables inside environment[.prod].ts file.

You can import those variables by

import { environment } from 'environments/environment';

this code.and use as below

environment.baseURL...;

2) Regarding to the header and body, also parameters of http request you can create new service extends from HTTP.

@Injectable()
export class HttpHelperService {

  constructor(
    private http: Http
  ) { }

  private generateReqOptions(isUrlEncoded = false, requiredAuth = false, customHeader?: Headers , customParam?: Object): RequestOptions {
...
  }

  get(url: string, query: Object, requiredAuth = false, headers?: Headers): Observable<any> {
...
  }

  post(url: string, body: any, isUrlEncoded = false, requiredAuth = false, headers?: Headers): Observable<any> {
...
  }

  private handleError (error: Response | any) {
    ...
  }
}

You can add custom handling functions like this.

And make http request as below.

  constructor(
    private http: HttpHelperService
  ) { }


  getReasons() {
    return this.http.get(...)
      .map(x => x.json())
  }

I hope this will help you.

Liu Zhang
  • 1,808
  • 19
  • 31
0

you can create a file and named it like url.constants.ts and placed this file in /app folder.

Write code in the url.constants.ts as below:

export const environment = {
  production: false,
  apiUrl: 'http://localhost:8000',
};

In any service.ts like product.service.ts file you can call them as like:

import { environment } from '../url.constants';
console.log(environment.production);
export class ProductService {
private url  = environment.apiUrl;
constructor(private http:HttpClient) {
  if(this.item != null){
    this.token = this.item.token;
  }
}

getProducts(): Observable<any>{
    const url = `${this.url}/api/product`;
    return this.http.get(url,{headers: new HttpHeaders({Authorization:'Bearer '+ this.token})});
}