4

I have some global variables in head's tag:

<script type="text/javascript">
    var apiRoot = 'http://localhost:8000/api',
        apiUrl = apiRoot,
        apiBadgeUrl = apiRoot + '/badges',
        apiLevelUrl = apiRoot + '/levels',
        apiBehaviorUrl = apiRoot + '/behaviors',
        apiTrophyUrl = apiRoot + '/trophies',
        apiUserUrl = apiRoot + '/users',
        apiWidgetPreferencesUrl = apiRoot + '/widgetPreferences';
</script>

I want to use in angular expression in html file but my tries are fails:

{{ $window.apiRoot }} or {{ apiRoot }} 

3 Answers 3

6

These expressions are evaluated against the current scope. If you have not set them in your scope via a controller, it will not evaluate. See http://docs.angularjs.org/guide/expression

Example:

function MyCtrl($scope)
{
   $scope.apiRoot = apiRoot;
}

HTML:

<div ng-controller="MyCtrl">
   {{apiRoot}}
</div>

As has been mentioned, while the above example works, it is not reccommended. The better way would be to set these variables in a service and then get them through the service.

function MyCtrl($scope, apiRootService)
{
   $scope.apiRoot = apiRootService.getApiRoot();
}

The service:

angular.module('myServices', []).factory('apiRootService', function() {
    var apiRoot = 'http://localhost:8000/api',
    apiUrl = apiRoot,
    apiBadgeUrl = apiRoot + '/badges',
    apiLevelUrl = apiRoot + '/levels',
    apiBehaviorUrl = apiRoot + '/behaviors',
    apiTrophyUrl = apiRoot + '/trophies',
    apiUserUrl = apiRoot + '/users',
    apiWidgetPreferencesUrl = apiRoot + '/widgetPreferences';
    return {
      getApiRoot: function() {
         return apiRoot
      },
      //all the other getters
   });
Sign up to request clarification or add additional context in comments.

4 Comments

While this method works it is very, very bad for unit testing :-(
@pkozlowski.opensource You are absolutely correct. I've updated my answer to show the more correct way. Please correct me if I'm wrong in my update.
It should (I think) be called apiRootService (without the dollar sign). Angular uses the dollar sign for its internal names.
There's no reason the service couldn't have the $ on front, but, you're right, it's recommended that you don't. I've updated the answer.
1

The best practice is to move apiRoot to a Service and inject that service into your controller. See here.

Comments

0

Another way to do this would be to add your global's to the $rootScope. You can do this by adding the following to your app module definition

angular.module('myApp', ['ngRoute'])
    .run(function ($rootScope){
        $rootScope.myAPI = {
             apiRoot: 'http://localhost:8000/api',
             apiUrl: apiRoot,
             apiBadgeUrl: apiRoot + '/badges',
             apiLevelUrl: apiRoot + '/levels',
             apiBehaviorUrl: apiRoot + '/behaviors',
             apiTrophyUrl: apiRoot + '/trophies',
             apiUserUrl: apiRoot + '/users',
             apiWidgetPreferencesUrl: apiRoot + '/widgetPreferences'
        }
    });


While a service does work, the angular documentation recommends against this. http://docs.angularjs.org/misc/faq

Conversely, don't create a service whose only purpose in life is to store and return bits of data.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.