Change ng-show value in other controller - javascript

I'm trying to show and hide a div using ng-show. It's a navbar that I want to show only in some views.
I have a controller which "controls" that div. And in other controller I want to edit this ng-show value in order to hide or show the div (navbar).
I tried different things as using a $rootScope, a timeout, an $apply, a factory... but nothing works.
So I'm asking here if anyone could help me.
(Sorry for my English)
This is my html and js codes (last edit code)
<div id="main">
<!-- AquĆ­ inyectamos las vistas -->
<div ng-controller="appCtrl" ng-show="isLogged" class="navbar navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>
<a class="navbar-brand" href="#/">Aula Virtual</a> </div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav" style="text-align: right">
<li class="active">Home</li>
<li>Users</li>
<li>Operaciones</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</div>
<div class="connect">
<div class="container">
<p>
Aula Virtual para profesorado y alumnos de la universidad
</p>
</div>
</div>
</div>
<div ui-view></div>
</div>
I tried a (ng-show="isLogged==false") too.
The controller of the div:
.controller('appCtrl', function($scope, $rootScope) {
console.log($scope.isLogged); //---> this shows undefined
});
The controller where I want to edit the isLogged value:
cities2.controller('userCtrl',['rootScope', '$scope', '$state','$http','md5', function($rootScope, $scope, $state, $http, md5) {
$rootScope.$apply(function(){
$rootScope.isLogged = true;
});
Thanks for the help!

It's good practice to use services to share data between controllers.
cities2.controller('appCtrl', ['$scope', 'LoggedStatus', function($scope,LoggedStatus) {
$scope.LoggedStatus = LoggedStatus;
}]);
cities2.controller('userCtrl', ['$scope', 'LoggedStatus', function($scope,LoggedStatus) {
$scope.LoggedStatus = LoggedStatus;
}]);
cities2.service('LoggedStatus', function() {
return {
isLogged: false
}
});
Changing the value of $scope.LoggedStatus.isLogged in either controller will change the value in both.

In your appCtrl controller, do $scope.isLogged=0. If you change this value to 1, the block will be visible else it will be hidden.
app.controller('appCtrl', function($scope) {
$scope.isLogged=0;
})
Refer to the plunker below:
https://plnkr.co/edit/d3q3QwA9k5f6ewXbqZ3M?p=preview

Well, finally I found the solution. I put this if can help someone:
I put a .run in the appCtrl where I initialize the ng-show:
.run(function ($rootScope) {
$rootScope.isLogged = false;
});
and now, when I put a true value in the other controller it works, and the navbar appears.
cities2.controller('userCtrl',['$rootScope', '$scope', '$state','$http','md5','$sessionStorage', function($rootScope, $scope, $state, $http, md5, $sessionStorage) {
$rootScope.isLogged=true;
}]);

Related

ng-show and ng-hide doesn't work

My problem probably is simple. I want hide my intro section on all pages less at home.
The problem is that when you hide hiding on every page and when you show shows on every page. I plan to just hide in the home page "/".
html:
<!-- Intro Section -->
<section id="intro" class="intro-section" ng-show="home">
<div class="container">
<div class="row">
<a class="btn btn-default page-scroll scroll_btn floating" href="#slide">
<span class="glyphicon glyphicon-arrow-down"></span>
</a>
</div>
</div>
</section>
JS:
app.controller("employerCtrl", ["$scope", "$location", "$route", function($scope, $location, $route) {
var path = $location.path();
console.log(path);
$scope.home = true;
if(path === "/") {
console.log("Inside");
$scope.home = true;
} else {
console.log("Inside else");
$scope.home = false;
}
}]);
Take home as root scope and make it false in home controller and true in other controllers.
app.controller("homecontroller", ["$scope", "$location", "$route","$rootScope", function($scope, $location, $route,$rootScope) {
$rootScope.home = false;
}]);
app.controller("othercontroller", ["$scope", "$location", "$route","$rootScope", function($scope, $location, $route,$rootScope) {
$rootScope.home = true;
}]);
<section id="intro" class="intro-section" ng-show="home">
<div class="container">
<div class="row">
<a class="btn btn-default page-scroll scroll_btn floating" href="#slide">
<span class="glyphicon glyphicon-arrow-down"></span>
</a>
</div>
</div>
</section>

ng-repeat not displaying items

i have a weird bug in my angular app where the data in my ng-repeat is not displaying but if i refresh the page and navigate to my home page it quickly flickers into view then disappears, im not sure why this is happening can someone help me out?
thanks in advance
appRoutes.js
angular.module('appRoutes', []).config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
// home page
.when('/', {
templateUrl: 'views/home.html',
controller: 'MainController'
})
// characters page that will use the CharactersController
.when('/characters', {
templateUrl: 'views/characters.html',
controller: 'CharactersController'
});
$locationProvider.html5Mode(true);
}]);
CharactersCtrl.js
angular.module('CharactersCtrl', []).controller('CharactersController', function($scope) {
$scope.init = function(){
$scope.getCharacters();
}
$scope.getCharacters = function(){
$.ajax({
url:'https://gateway.marvel.com/v1/public/characters?apikey=APIKEY',
success:function(response){
$scope.characters = response.data.results;
console.log($scope.characters);
},
fail:function(){
}
});
}
$scope.init();
});
characters.js
<div>
<div class="text-center">
<h1>Characters</h1>
</div>
<section id="character-section" class="row">
<figure class="columns small-3" ng-repeat="hero in characters">
<!-- <img ng-src="{{hero.thumbnail.path}}" alt="{{hero.name}}-image"> -->
<figcaption>
{{hero.name}}
</figcaption>
</figure>
</section>
</div>
index.html
<body ng-app="marvelApp">
<!-- HEADER -->
<header>
<nav class="navbar navbar-inverse">
<div class="navbar-header">
<a class="navbar-brand" href="/">Stencil: Node and Angular</a>
</div>
<!-- LINK TO OUR PAGES. ANGULAR HANDLES THE ROUTING HERE -->
<ul class="nav navbar-nav">
<li>characters</li>
</ul>
</nav>
</header>
<!-- ANGULAR DYNAMIC CONTENT -->
<main ng-view ></main>
</body>
app.js
angular.module('marvelApp', ['ngRoute', 'appRoutes', 'MainCtrl', 'CharactersCtrl', 'CharactersService']);
You are using jQuery ajax. Angular does not automatically update variable when modified outside the Angular scope (in this case, $scope.characters is modified using jquery ajax);
I sugges you use the $http service provided by angular for making ajax calls.
But if you insist in using jquery ajax, you can wrap this code $scope.characters = response.data.results; with
`$scope.$apply(function(){
})`
Result:
$scope.$apply(function(){
$scope.characters = response.data.results;
})

How can I change the menu content after user log in

I have a menu bar defined in the "HomeController" with a login button.
My login form is a ui-bootstrap modal whose controller is "LoginController".
After successfully log in, user is directed to another state. But I also want the "Login" button to hide and show the current user's email.
I think I should use either localstorage or cookies to store the current user information. the localstorage data never expires so I think cookies is better?
So what should I do in my "LoginController" and "MainController"?
Can I use the $emit and $on?
I'm new to angular. Any suggestions would be appreciated.
.state('home', {
url: '/home',
templateUrl: 'template/partial-home.html',
controller:'mainController'
})
.state('login', {
url: '/login',
parent:'home',
onEnter:['$stateParams','$state','$modal','$resource',function($stateParams,$state, $modal, $resource){
$modal.open({
animation: true,
size:'',
templateUrl: 'login/login.html',
controller:'loginController'
}).result.then(function(){
console.log('promise resolved success');
$state.go('admin-dashboard',{});
},function(){
console.log('promise rejected fail');
}).finally(function(){
console.log('promise finally');
//$state.go('home',{});
});
}]
})
.controller('loginController',function($scope,$http,$timeout,AuthToken,$window){
$scope.badCreds = false;
$scope.cancel = function() {
$scope.$dismiss();
};
$scope.login = function() {
console.log($scope.credential);
$http.post('/authenticate',$scope.credential).then(function success(response){
console.log(response.data.token);
AuthToken.setToken(response.data.token);
$scope.currentuser = response.data.user;
$scope.alreadyLoggedIn = true;
console.log('success', 'Hey there!', 'Welcome ' + $scope.currentuser.email + '!');
$scope.$close();
},function error(response){
$scope.message='Problem logging in! Sorry!';
});
};
$scope.logout = function(){
AuthToken.clearToken();
$scope.currentuser = null;
//showAlert('info','Goodbye!','Have a great day!');
};
<body ng-controller="mainController">
<header>
<div class="nav navbar-default navbar-fixed-top" role="navigation">
<div class = "container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Westlake Pioneers</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a ui-sref="home" ui-sref-active="active"><i class="fa fa-home"></i>Home</a></li>
<li><a ui-sref="team" ui-sref-active="active"><i class="fa fa-shield"></i>Our Team</a></li>
<li><a ui-sref="blogs" ui-sref-active="active"><i class="fa fa-book"></i>Blogs</a></li>
<li><a ui-sref="projects" ui-sref-active="active"><i class="fa fa-wrench"></i>Projects</a></li>
<li><a ui-sref="contact" ui-sref-active="active"><i class="fa fa-comment"></i> Contact</a></li>
<li><a ng-hide="$rootScope.currentuser" ui-sref="login" ui-sref-active="active"><i class="fa fa-sign-in"></i></i>Login</a></li>
<li>{{currentuser.email}}</li>
</ul>
</div>
</div>
</div>
</header>
<div id="main">
<div class="page {{pageClass}}" ui-view>
</div>
</div>
To pass a parameter into a view when using ui-router do the following:
Add "params" field in your 'home' route definition with an object that will hold the user name ($stateProvider API):
.state('home', {
url: '/home',
templateUrl: 'template/partial-home.html',
controller:'mainController',
params : { userName: null }
})
When closing modal, pass the user name of logged in user back to source (add $uibModalInstance as dependency to login controller, what's $scope.$close()?):
$uibModalInstance.close(response.data.user);
Accept the username in your modal declaration:
.result.then(function (loggedInUserName)
Call $state.go and pass the username to the view:
$state.go('admin-dashboard',{userName:loggedInUserName});
Finally inject $stateParams to the controller that handles 'admin-dashboard' view and access it using $stateParams.userName
Alternatively, if you would like to make username available to the whole application, you can just store it in the $rootScope(dirty) or make an angular service (better).
Good luck!

$rootScope to set active tab not working

would anyone be able to help me on this issue I am having?
I have a NavCtrl for manage my active tag, I was able to change the active tab when click on the menu item, however when I click on the link in the body views, it take me to the page I want to, but the active tag is not change.
//controller for nevigation menu
sp.controller('NavCtrl', ['$scope', 'auth', '$window','$rootScope', function ($scope, auth, $window,$rootScope) {
$scope.LogOut = auth.logOut;
$scope.isLoggedIn = auth.isLoggedIn;
$scope.tab = $rootScope.navTav;
$scope.toTop = function(){
$window.scrollTo(0, 0);
};
}]);
I try to use the $rootScope to set the navTab, but it's still not working
//setting root scope
sp.run(function($rootScope) {
$rootScope.navTav = 1;
})
ui-Router
.state('qaanswer', {
url: '/qa/{quesId}',
views: {
view50': {
templateUrl: './qa/qaanswer.html',
controller: 'QAAnswerCtrl'
},
'view60': {
templateUrl: './shareviews/activityupdates.html',
controller: 'HomeCtrl'
}
},
onEnter:['$rootScope',function($rootScope){
$rootScope.navTav = 5;
}]
Thank you so much for the help
Update HTML :
<body ng-controller="NavCtrl">
<!-- Desktop Menu -->
<div>
<div>
<ul>
<a href="#/home" ng-class="{active: navTab === 1}" ng-click="navTab = 1">
<li>Home</li>
</a>
<a href="#/qa" ng-class="{active: navTab === 2}" ng-click="navTab = 2">
<li>QA</li>
</a>
</ul>
</div>
</div>
<div>
<div>
<div class="row">
<div ui-view="view50"></div>
<div ui-view="view60"></div>
</div>
</div>
</div>
</body>
Working plunker
You can simplify your implementation and have no issues. Simply use the $rootScope variable directly in your template along side ng-class like so:
<body ng-controller="NavCtrl">
<a ng-class="{red: $root.navTab===0}" ui-sref="first">first</a>
<a ng-class="{red: $root.navTab===1}" ui-sref="second">second</a>
<div ui-view></div>
</body>
Then update $rootScope in your controllers.
.controller('NavCtrl', function($scope, $rootScope) {});
.controller('FirstCtrl', function($scope, $rootScope) {
$rootScope.navTab = 0;
});
.controller('SecondCtrl', function($scope, $rootScope) {
$rootScope.navTab = 1;
});
Your states get to stay relatively simple:
.state('first', {
url: '/first',
templateUrl: 'first.html',
controller: 'FirstCtrl'
})
.state('second', {
url: '/second',
templateUrl: 'second.html',
controller: 'SecondCtrl'
})
plunker
Ideally you would make a directive for such a task, and avoid using $rootScope. A simple way to do this is to broadcast a message whenever you land on a new page, then listen on that event in your tab directive and flip the correct tab as active.

Bind value to ng-switch in Angular template

I am new to Angular. I have a directive that displays the navigation:
(function(){
angular
.module('instaguideApp')
.directive('navigation', navigation);
function navigation(authenticationData){
return {
restrict: 'EA',
templateUrl: '/common/directives/navigation/navigation.template.html',
scope: false,
link: function(scope, elem, attr) {
scope.data = {
isLoggedIn: authenticationData.isLoggedIn
};
}
};
}
})()
navigation.template.html is:
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">InstaGuide
<button type="button" data-toggle="collapse" data-target="#navbar-main" class="navbar-toggle"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div id="navbar-main" class="navbar-collapse collapse">
<ul ng-switch="{{data.isLoggedIn}}" class="nav navbar-nav">
<li>About</li>
<li ng-switch-default>
Login
</li>
<li ng-switch-when="true">>
Logout
</li>
<li>Debugging Value: {{data.isLoggedIn}}</li>
</ul>
</div>
</div>
</div>
I have a service which stores the login state of the user:
(function(){
angular
.module('instaguideApp')
.service('authenticationData', authenticationData);
function authenticationData(){
var auth = {
isLoggedIn: false
};
return auth;
}
})();
Once I successfully log in, i set "isLoggedIn" of authenticationData to true. When this happens I want to show Logout in the navigation rather than Login. You can see I am using ng-switch in an attempt to achieve this.
When I login, the template receives that I have logged in because I can see that "Debugging Value: false" changes to "Debugging Value: true".
However, Login and Register still appear in the menu, as if ng-switch has not registered that it's value has changed. Any idea how to achieve this?
Try removing the parentheses in the ng-switch value:
<ul ng-switch="data.isLoggedIn" class="nav navbar-nav">
ng-switch is expecting angular expression as its value. So there is no need to wrap the value into double parentheses.

Categories