0

I have multiple clients on my angular app and I want to create different themes inside angular (only the visual part will change, controllers remain the same.

I have a "security" module which manages the authentication, currentLoggedIn user and so on.

var security = angular.module('security', ['ui.router'])
    // .factory('authService',  authService);
.service('authService', ['$http', '$q', '$window', 'CONSTANTS', '$location', 'currentUser', '$state', '$rootScope', authService])
.factory('authCheck', ['$rootScope', '$state', 'authService', securityAuthorization])

and authService is basically having these methods/values

service.login = _login;
    service.logout = _logout;
    service.reset = _reset;
    service.isAuthenticated = _isAuthenticated;
    service.requestCurrentUser = _requestCurrentUser;
    service.returnCurrentUser = _returnCurrentUser;
    service.hasRoleAccess = _hasRoleAccess;

How can I get access to currentUser inside templateURL function to modify the URL based on data for currentUser? AuthService and AuthCheck are empty when accessed in templateURL function.

$stateProvider
        .state('home', {
            url: '/home',
            templateUrl: function(authService, authCheck) {
                console.log (authService, authCheck);
                return 'components/home/home.html'
            },
            data: {
                roles: ['Admin']
            },
            resolve: {
                "authorize": ['authCheck', function(authCheck) {
                    return authCheck.authorize();
                }],
                "loadedData": ['metricsFactory', 'campaignFactory', '$q', '$rootScope', 'selectedDates', loadHomeController]
            },
            controller: 'HomeController',
            controllerAs: 'home'
        });
Alexandru R
  • 8,560
  • 16
  • 64
  • 98
  • Why don't you add that logic to the view itself? Seems easier for me, you'll show different part of layout depending on `currentUser` properties. – Frondor Sep 05 '15 at 10:06

2 Answers2

1

In case, we want to do some "magic" before returning the template... we should use templateProvider. Check this Q & A:

Trying to Dynamically set a templateUrl in controller based on constant

Because template:... could be either string or function like this (check the doc:)

$stateProvider

template

html template as a string or a function that returns an html template as a string which should be used by the uiView directives. This property takes precedence over templateUrl.

If template is a function, it will be called with the following parameters:

{array.} - state parameters extracted from the current $location.path() by applying the current state

template: function(params) {
    return "<h1>generated template</h1>"; }

While with templateProvider we can get anything injected e.g. the great improvement in angular $templateRequest. Check this answer and its plunker

templateProvider: function(CONFIG, $templateRequest) {
    console.log('in templateUrl ' + CONFIG.codeCampType);

    var templateName = 'index5templateB.html';

    if (CONFIG.codeCampType === "svcc") {
         templateName = 'index5templateA.html';
    } 

    return $templateRequest(templateName);
},
Community
  • 1
  • 1
Vaibhav Pachauri
  • 2,671
  • 2
  • 19
  • 32
0

From the documentation:

templateUrl (optional)

path or function that returns a path to an html template that should be used by uiView.

If templateUrl is a function, it will be called with the following parameters:

{array.<object>} - state parameters extracted from the current $location.path() by applying the current state

So, clearly, you can't inject services to the templateUrl function.

But right after, the documentation also says:

templateProvider (optional)

function

Provider function that returns HTML content string.

templateProvider:
    function(MyTemplateService, params) {
      return MyTemplateService.getTemplate(params.pageId);
    }

Which allows doing what you want.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255