I have a set of tabs as module tags which all must be siblings to each other and first children of the main-view container.
I want to invoke the first two interchangibly if the user is authenticated.
I can verify isAuthenticated
is available in the scope, but the conditions I have are not being respected. Additionally, for performance reasons, I'd like to avoid invoking the entire hidden module.
What am I doing wrong and what's the best conditional for including a set of module tags?
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-if="isAuthenticated == true"
<!--ng-show="isAuthenticated == true"
ng-hide="isAuthenticated == false" i've tried all these directives and none work -->
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-if="isAuthenticated == false"
<!--ng-hide="isAuthenticated == true"
ng-show="isAuthenticated == false"-->
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
user-login module:
import 'angular';
var app = angular.module('user-login', ['sol-backend', 'services'])
.constant('AUTH_EVENTS', {
loginSuccess: 'auth-login-success',
loginFailed: 'auth-login-failed',
logoutSuccess: 'auth-logout-success',
sessionTimeout: 'auth-session-timeout',
notAuthenticated: 'auth-not-authenticated',
notAuthorized: 'auth-not-authorized'
})
.constant('USER_ROLES', {
all: '*',
admin: 'admin',
editor: 'editor',
guest: 'guest'
})
.directive('userLogin',
['$rootScope', '$window', '$timeout', '$http', '$location', 'solBackend', 'AUTH_EVENTS', 'USER_ROLES',
($rootScope, $window, $timeout, $http, $location, solBackend, AuthService, AUTH_EVENTS, USER_ROLES) => {
return {
restrict: 'E',
templateUrl: '/modules/user-login/user-login.html',
replace: true,
scope: true,
link: function ($scope, element, attrs) {
console.log('userLogin Directive: ', AUTH_EVENTS, $scope.isAuthenticated);
$scope.currentUser = false;
$scope.isAuthenticated = false;
$rootScope.currentUser = false;
$rootScope.isAuthenticated = false;
var cookie = false;
var value = "; " + document.cookie;
var parts = value.split("; " + 'tacsession' + "=");
if (parts.length == 2) cookie = parts.pop().split(";").shift();
console.log('cookie', cookie);
if (cookie.length > 10) {
$http.get('https://localhost.trackauthoritymusic.com/json/getme')
.then(function(res) {
if (res.data.error) {
console.log('tacsession failed', res.data.error);
} else if (res.data.user_id) {
$scope.setCurrentUser(res.data);
}
},
function(response) { // optional
console.log('cookie rejected', response);
});
}
// /json/getme > IF VALID set, ELSE reject
$scope.toggleGoogleAuth = () => {
if (!$scope.authenticated)
solBackend.authenticateWithPopup();
else
solBackend.unauthenticate();
};
solBackend.getAuth().then(($auth) => {
$auth.$onAuth((auth) => {
if (auth && auth.uid) {
$scope.authenticated = true;
$scope.authData = auth.google;
}
else {
$scope.authenticated = false;
}
});
});
}
};
}])
.factory('AuthService', function ($http, Session) {
var authService = {};
authService.login = function (credentials) {
function serializeParams(obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
for(i=0; i<value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value instanceof Object) {
for(subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
return query.length ? query.substr(0, query.length - 1) : query;
};
return $http({
url: 'https://localhost.trackauthoritymusic.com/manage/users/login?tar=doAjax',
method: "POST",
dataType: 'json',
data: serializeParams(credentials)
})
.then(function(res) {
Session.create(res.data);
return res.data;
},
function(response) { // optional
console.log(response);
});
};
authService.isAuthenticated = function () {
console.log('checking isAuthenticated', Session);
return Session.user_id < 1;
};
authService.isAuthorized = function (role) {
console.log('question isAuthorized: ' + role, USER_ROLES);
return (authService.isAuthenticated() && typeof USER_ROLES[role] == 'object' && USER_ROLES[role] > 2);
};
return authService;
})
.factory('AuthResolver', function ($q, $rootScope, $state) {
return {
resolve: function () {
var deferred = $q.defer();
var unwatch = $rootScope.$watch('currentUser', function (currentUser) {
console.log('watching currentUser ', currentUser);
if (angular.isDefined(currentUser)) {
if (currentUser) {
console.log('currentUser defined');
deferred.resolve(currentUser);
} else {
deferred.reject();
$state.go('user-login');
}
unwatch();
}
});
return deferred.promise;
}
};
})
.service('Session', function () {
this.create = function (me) {
this.me = me;
this.user_id = parseInt(me.user_id);
this.user_status = parseInt(me.user_status);
};
this.destroy = function () {
this.me = null;
this.user_id = -1;
this.user_status = 0;
};
})
.controller('LoginController', function ($scope, $rootScope, AUTH_EVENTS, AuthService) {
console.log('LoginController: ', AUTH_EVENTS);
$scope.credentials = {
user_email: '',
password: ''
};
$scope.login = function (credentials) {
console.log('Sending credentials: ', $scope.credentials);
AuthService.login(credentials).then(function (user) {
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
$scope.setCurrentUser(user);
}, function () {
$rootScope.$broadcast(AUTH_EVENTS.loginFailed);
});
};
})
.config(function ($httpProvider) {
$httpProvider.interceptors.push([
'$injector',
function ($injector) {
return $injector.get('AuthInterceptor');
}
]);
})
.factory('AuthInterceptor', function ($rootScope, $q, AUTH_EVENTS) {
return {
responseError: function (response) {
$rootScope.$broadcast({
401: AUTH_EVENTS.notAuthenticated,
403: AUTH_EVENTS.notAuthorized,
419: AUTH_EVENTS.sessionTimeout,
440: AUTH_EVENTS.sessionTimeout
}[response.status], response);
return $q.reject(response);
}
};
});
app.run(function ($rootScope, AUTH_EVENTS, AuthService) {
console.log('RUNNING USER-LOGIN: ', AUTH_EVENTS);
$rootScope.$on('$stateChangeStart', function (event, next) {
console.log('state change start', next.data);
if (!AuthService.isAuthenticated()) {
event.preventDefault();
console.log('NOT AUTHENTICATED: ' + AUTH_EVENTS.notAuthenticated);
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
});
});
export default app;
ambiane-pane module:
import 'angular';
export default angular.module('ambiance-pane',
['sol-backend', 'services', 'filters'])
.directive('ambiancePane',
['$rootScope', '$window', '$timeout', '$http', '$location', 'youtubeAPI', 'taAPI', 'playList', 'solBackend',
($rootScope, $window, $timeout, $http, $location, youtubeAPI, taAPI, playList, solBackend) => {
return {
restrict: 'E',
replace: true,
templateUrl: '/modules/ambiance-pane/ambiance-pane.html',
scope: {},
link: ($scope, $element) => {
console.log("AMBIANCE LINKED playList.playlist", playList.playlist, $scope.isAuthenticated);
Object.assign($scope, {
challenge_id:null,
active: false,
status: 'active',
users_count:0,
track_scount:0,
challenge_id:-1,
track_list:[],
track_order:{},
author_id:-1,
ta_id:-1
});
},
controller: function($scope, $element, $attrs) {
$scope.challenges = [{challenge_id:-1,challenge_title:"My custom playlist",group_id:-1}];
$scope.challenge = null;
$scope.selectedChallengeItem = [0];
$scope.currentUser = false;
$scope.isAuthenticated = false;
var cid = playList.getNowPlayingIdx();
var state = playList.getState();
console.log('ambiance-pane knows isAuthenticated', $scope.isAuthenticated);
if (true || $scope.isAuthenticated) {
taAPI.getChallenges().then(function(response) {
if (typeof response.popBody == 'object') {
console.log('ALL CHALLENGES: ', response);
var options = response.popBody;
options['_-1'] = {challenge_id:-1,challenge_title:"My custom playlist",group_id:-1};
$scope.challenges = options;
for(var i in response.popBody) {
$scope.selectedChallengeItem = response.popBody[i];
break;
}
if ($scope.selectedChallengeItem.challenge_id > 0) {
var cid = $scope.selectedChallengeItem.challenge_id;
taAPI.getTAplaylist(cid).then(function(response) {
console.log('GOT CHALLENGE: ', response);
$scope.challenge = response.popBody;
});
}
}
});
}
$scope.items = playList.playlist;
$scope.$watch(() => playList.metadata, (newVal, oldVal) => {
if (!!newVal) {
newVal.$bindTo($scope, "metadata");
} else {
$scope.metadata = null;
}
if (oldVal) {
oldVal.$destroy();
}
});
$scope.getChallenge = function(){
return $scope.challenge;
}
}
}
}])
.directive('challengeBlock', function ($compile) {
var definitions = {
restrict: 'E',
templateUrl: '/html/playlist/challengeBlock.html',
replace: true,
scope: true,
transclude:true,
link: function($scope, $element, $attrs) {
$scope.dataSources = {
ci: 'https://localhost.trackauthoritymusic.com',
angular: 'https://localplayer.trackauthoritymusic.com',
api : 'https://localhost.trackauthoritymusic.com'
}
}
};
return definitions;
});
application module that invokes all others:
[import '...whole project'];
const cacheUpdated = new Promise((resolve, reject) => {
if (window.hasOwnProperty('applicationCache')) {
window.applicationCache.addEventListener('updateready', function() {
resolve();
});
}
});
export default angular.module('Application', [..references..]).constant('DATA_SOURCES', {
ci: 'https://localhost.trackauthoritymusic.com',
angular: 'https://localplayer.trackauthoritymusic.com',
api : 'https://localhost.trackauthoritymusic.com'
}).directive('solarizdApp', ['$rootScope', 'ApiKey', 'playList', 'solBackend', function($rootScope, ApiKey, playList, solBackend) {
return {
restrict: 'E',
templateUrl: '/html/app.html',
replace: true,
scope: true,
link: function($scope, $element) {
$scope.currentUser = false;
$scope.isAuthenticated = false;
//$rootScope.currentUser = false; // doesn't help
//$rootScope.isAuthenticated = false;
$scope.setCurrentUser = function (user) {
console.log("setting global user", user);
$scope.currentUser = user;
if (user.user_id > 0) {
$scope.isAuthenticated = user.group_user_status;
}
};
ApiKey.fetchKeys().then(function() {
$element[0].classList.add('loaded');
});
// Notify users when there's a new version
cacheUpdated.then(() => {
$rootScope.$broadcast('toast::notify', {
text: 'Reload this app to get a newer version',
persist: true
});
});
},
controller : function($scope, $rootScope) {
console.log('solarizdApp controller');
$scope.currentUser = false;
$scope.isAuthenticated = false;
$scope.setCurrentUser = function (user) {
console.log("setting global user from controller", user);
$scope.currentUser = user;
if (user.user_id > 0) {
$scope.isAuthenticated = user.group_user_status;
}
};
}
};
}])
.config(["$httpProvider", function($httpProvider) {
$httpProvider.interceptors.push('middleware');
}]).factory('middleware', function() {
return {
request: function(config) {
if (config.url.indexOf("trackauthoritymusic.com") > -1) {
console.log("HTTP REQUEST", config);
if (!config.headers || typeof config.headers != 'object') {
console.log('instantiating headers???');
config.headers = {};
}
config.withCredentials = true;
config.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
}
return config;
}
};
});
You can do that in all three module tags which will yield similar solutions.
Possible ways:
Using ng-if alone as
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-if="isAuthenticated"
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-if="isAuthenticated"
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
Use ng-show alone
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-show="isAuthenticated"
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-show="isAuthenticated"
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
Finally, Using ng-hide
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-show="isAuthenticated"
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-show="isAuthenticated"
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
Best practise
Using ng-if.
Why?
The particular element will be retrieved only if the condition is satisfied, so your browser might not show the markup in the Developer Tools
If element contains some data, image that is to be loaded only if the condition is satisfied
Hope this helps you.