Marco Aurélio Deleu
Marco Aurélio Deleu

Reputation: 4367

How to set a base URL for HTTP calls and image loading with AngularJS

I've been searching and so far I couldn't find a way to handle the following situation:

I'd like to have one variable that represents my domain, something like http://example.com/myserver/. Anything that I would want to access is sublocaled in that domain. Such variable should be available for me in all Services as well as from HTML (for image loading purpose). For instance:

angular.module('App', ['App.providers', 'App.services', 'App.controllers', 'App.directives']).run('EndpointFactory', [function (EndpointFactory) {
    EndpointFactory.BASE = 'http://www.example.com/mydata';
}]);

angular.module('App.services', []).factory('PrizeService', ['$http', 'EndpointFactory', function ($http, EndpointFactory) {
    return {
        index: function () {
            return $http.post(EndpointFactory.BASE + '/prizes', {});
        }
    };
}]);

This example above was one of my failed trials. Although I don't like the idea of having to inject a Factory at every Service, I was willing to do it until I faced the <img ng-src /> tag.

<div>
   <img ng-src="{{EndpointFactory.BASE + prize.imagePath}}" />
</div>

I can't access the EndpointFactory from this directive and I don't want to have to copy data from the factory to a $scope in every controller.

Upvotes: 2

Views: 3550

Answers (2)

Nour Lababidi
Nour Lababidi

Reputation: 444

Here is an

example with Angular 6 (I'm not sure if it will work for AngularJs)

related to what you want which I found to be the cleanest way. I hope this will make sense to you and save you some time. Best of Luck!

Create a new file named baseurl.ts in the shared folder and update its contents as follows:

export const baseURL = 'http://localhost:3000/';

Open AppModule, import baseURL and update the AppModule's providers property of the @NgModule decorator as follows:

. . .
import { baseURL } from './shared/baseurl';


. . .


providers: [

  . . .

  {provide: 'BaseURL', useValue: baseURL}
  ]

Updating Menu Component Open menu.component.ts and update it as follows:

import { Component, OnInit, Inject } from '@angular/core';

. . .

  constructor(private dishService: DishService,
    @Inject('BaseURL') private BaseURL) { }
    
. . .

Open menu.component.html and update it as follows:

. . .
        <img height="200px" src="{{BaseURL + dish.image}}" alt={{dish.name}}>

. . .

[Reference] This example came from Coursera.com https://www.coursera.org/learn/angular/lecture/Mgo5H/exercise-video-angular-http-client

Upvotes: 0

scniro
scniro

Reputation: 16979

You can use constants. Observe the following...

module.constant('BASE', 'http://example.com/myserver/');

This value can then be injected anywhere e.g.

module.factory('PrizeService', ['$http', 'BASE', function ($http, BASE) {
    console.log(BASE) // -- http://example.com/myserver/
    /*...*/
}]);

For templates, you could always then slap this on $rootScope in your run block for reference anywhere as such...

module.run(['$rootScope' , 'BASE', function($rootScope, BASE) {
    $rootScope.base = BASE;
}]);

<img ng-src="{{ base + prize.imagePath }}" />

Alternatively, you can of course inject and assign this constant to individual scopes opposed to $rootScope, but this sounds like a global value and could be an appropriate fit.

JSFiddle Link - demo showcasing both $rootScope and factory value injection

Upvotes: 2

Related Questions