7

I have developed few angular app with .NET Core , but every time Angular app is separate and .NET Core API is separate .

Now I am developing Angular app using inbuilt Angular template which include API in the same project.

I used to call api with full url (by defining base url as http://portNumber: in a service) but in this inbuilt template this is what I get

    export class FetchDataComponent {
  public forecasts: WeatherForecast[];

  constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
      this.forecasts = result;
    }, error => console.error(error));
  }
}

its a inbuilt component comes with angular template

Here its written as

http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts')

After some searching I found a method getBaseUrl() in main.ts with a constant providers as

   export function getBaseUrl() {
      return document.getElementsByTagName('base')[0].href;
    }
const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];

Now can someone explain me how Base Url from here got there in components as @Inject('BASE_URL') without sharing it in a service ?

in angularJS I used to the same with the help of @url.action

$http({
        url: "@Url.Action("Action", "Controller")",
        params: { StaffCode: $scope.staffid },
        method: "GET",
     }) 

Can we do this in angular 5 too ? and how is value of 'BASE_URL' is getting shared without creating a service ??

Tanwer
  • 1,503
  • 8
  • 26
  • 41

3 Answers3

5

If you open your main.ts file, you will find a function and a provider like this:

export function getBaseUrl() {
  return document.getElementsByTagName('base')[0].href;
}

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];

Notice how the provider is getting the value from the useFactory. And then you will see that using that provider, the main module is being generated:

platformBrowserDynamic(providers).bootstrapModule(AppModule);

And now the provider is injected in your component

constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
}

You can learn more about providers here

Anup Sharma
  • 2,053
  • 20
  • 30
  • 1
    Can you elaborate on this? It is still not clear to me, where the base url, e.g. `localhost:48192`, is read from, from this – thesystem Feb 04 '22 at 18:41
  • 1
    @thesystem When you open the index.html file, you will find the tag named base. The href attribute of that tag is the value you are looking for and that's what getBaseUrl() function is getting. Usually its relative value like '/' but you can set it whatever you want your base address to be. – Anup Sharma Feb 05 '22 at 09:23
  • Okay thanks, but if it does indeed refer to simply '/', then the base url is truly never set, like it is not told to look for specific url or port - however, it still know how to connect to the backend, which is served at `localhost:xxxxx`. I assume Microsoft handles this behind the scene, so that the angular frontend is automatically connected to the .NET backend project. – thesystem Feb 06 '22 at 18:36
  • 1
    @thesystem, based on what I know here is the explaination: The application can run in 2 configuration, Debug and Release. When you are in release mode, then only 1 application is running, i.e. backend. you open the link to the application and it will serve you the index.html page from angular dist folder and all the required javascript and css files will load as contents. However, when you are in debug mode then 2 application is running, 1)backend on one port, 2)angular on another. When you run the app, backend runs and then redirected to frontend which then use proxy to call on backend. – Anup Sharma Feb 08 '22 at 10:07
0

You can get Base_URL value using enviroment.ts. Here is my sample.

export const environment = {
  production: false,
  serverUrl: 'http://localhost:51316',
  authKey: 'currentUserInfo',
  cookieKey: 'isLogin'
};

And in my service I simply do this

   login(userCredentials: UserCredentials): Observable<any> {
        const loginUrl =  `${environment.serverUrl}/auth?grant_type=password&username=${userCredentials.account}&password=${userCredentials.password}`;
        return this.http.get(loginUrl);
    }

Full source code can be found here and here

  • 1
    do you realize what you doing ? , you are hard coding Base URL , Code will not be of dynamic nature anymore like this – Tanwer Aug 02 '18 at 09:35
  • It local development so is ok to hard code. If you want dynamic take a look [on](https://stackoverflow.com/questions/43403649/how-to-get-full-base-url-including-server-port-and-protocol-in-angular-univer) –  Aug 02 '18 at 10:31
0

For this to work, you need 4 files that .net core generate for you. main.ts, angular.json, aspnetcore-https.js as well as proxy.conf.js. Make sure that you have these file in the root directory, with minimal required content below.

The main.ts provides the BASE_URL constant like this

export function getBaseUrl() {
  return document.getElementsByTagName('base')[0].href;
}

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps:[] }
];

platformBrowserDynamic(providers)
 .bootstrapModule(AppModule);

In angular.json file, you need to configure the proxy file in the server tag like this

...,
"serve": {
 "builder": "@angular-devkit/build-angular:dev-server",
 "configurations": {
      "production": {
      "browserTarget": "packecr_compta:build:production"
      },
 "development": {
     "browserTarget": "packecr_compta:build:development",
     "proxyConfig": "proxy.conf.js"
        }
       },
   "defaultConfiguration": "development"
  },
 ...

Here's the content of the proxy.conf.js file

const { env } = require('process');
const target = env.ASPNETCORE_HTTPS_PORT ?    
 `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :    
 env.ASPNETCORE_URLS ?
env.ASPNETCORE_URLS.split(';')[0] :
'http://localhost:25148';

const PROXY_CONFIG = [
  {
    context: [
      "/weatherforecast",
      "/_configuration",
      "/.well-known",
      "/Identity",
      "/connect",
      "/ApplyDatabaseMigrations",
      "/_framework"
   ],
    target: target,
    secure: false,
    headers: {
      Connection: 'Keep-Alive'
    }
  }
]

module.exports = PROXY_CONFIG;
Bellash
  • 7,560
  • 6
  • 53
  • 86