AngularJS using $watch in controllers - angularjs

So I have been reading this article which suggests using $watch in your controllers is bad.
I am trying to take the advice. I have controller that looks like this:
.controller('NavigationController', ['$rootScope', '$scope', function ($rootScope, $scope) {
var self = this;
// Get our current user
self.user = $rootScope.user;
// Watch
$scope.$watch(function () {
// Return our user
return $rootScope.user;
}, function (user) {
// Set our user to the new user
self.user = user;
});
}]);
and my HTML looks like this:
<div class="account-header" ng-controller="NavigationController as controller" ng-cloak ng-show="controller.user.authenticated">
<div class="container">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-account">
<div class="collapse navbar-collapse" id="account-menu">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown" dropdown>
<a class="dropdown-toggle" dropdown-toggle>{{ controller.user.userName }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a ui-sref="teams">Team settings</a></li>
<li><a ui-sref="account">Account settings</a></li>
<li><a ui-sref="logout">Sign out</a></li>
</ul>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
</div>
You can see that I am only showing the account menu when the user is logged in. After reading the article, I am struggling to see how I can actually change my controller.
Does anyone have any suggestions?
Update 1
Some of you have said because it is in the rootscope, I don't have to do anything. I can just use user in the HTML and it should work fine.
I tested this like this:
<div class="account-header" ng-cloak ng-show="user.authenticated">
<div class="container">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-account">
<div class="collapse navbar-collapse" id="account-menu">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown" dropdown>
<a class="dropdown-toggle" dropdown-toggle>{{ user.userName }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a ui-sref="teams">Team settings</a></li>
<li><a ui-sref="account">Account settings</a></li>
<li><a ui-sref="logout">Sign out</a></li>
</ul>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
</div>
and it did work.
Now what I want to do is add another menu item, this item is only shown if there are any kits. But I would rather not do a API call on every state change, so the only thing I can see is to amend something when a kit is either added or deleted.
But I am not sure what is the best way to do this.

When the user changes broadcast a 'userLoggin' event on the $rootScope. Then listen for that event in your controller.
Or $emit the event on $rootScope and in the controller listen on the $rootScope by injecting it.
$rootScope.$on('userLoggin' function() {
// React to user change.
})

Related

one contoller file adding to another controller in angularjs

Here i am trying to add one page controller adding to another controller using same module in angular js. how can i add ctrl2.js menu to inside ctrl1.js.please help me currently i am using angualrjs one .. i am struck in this issue please give me a solution ...
menu.html:
<div id="left-top" ng-controller="two">
<ul class="nav navbar-nav navbar-right menu-top-left col-sm-12 col-xs-12">
<li>
<a href="#/">
<i class="material-icons mobile-menu-icon-color">exit_to_app</i>
<span class="notification mobile-menu-icon-color">Logout</span>
</a>
</li>
<li>
<a href="#">
<i class="material-icons mobile-menu-icon-color">person</i>
<span class="notification mobile-menu-icon-color">{{name}}</span>
</a>
</li>
</ul>
</div>
ctrl1.js
var app=angular.module('board',[]);
app.controller('one',function($scope){
alert("ctrlone');
});
ctrl2.js
var app=angular.module('board',[]);
app.controller('two',function($scope){
});
<div ng-controller="firstController">
<div ng-controller="secondController"></div>
</div>
if you want to use common $scope(your data) for ctrl1 and ctrl2, you need to create service for this, and after inject service to ctrl1, and ctrl2

angularjs : html header refresh after loggedin

I'd like to have a different header in my index.html (loggedout) and my home page (loggedin). I've tried many solution but my header never refresh. I always need to reload the page to make it work.
index.html
<div id="header" ng-controller="HeaderCtrl as head">
<div ng-show="head.loggedIn" class="header">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li><a ng-href="#/about">About</a></li>
<li><a ng-click="head.logout()">Logout</a></li>
</ul>
</div>
<div ng-show="head.loggedOut" class="header">
<ul class="nav navbar-nav">
<li><a ng-click="head.login()">Home</a></li>
<li><a ng-href="#/register">Sign in</a></li>
</ul>
</div>
</div>
<div class="container">
<div ng-view=""></div>
</div>
<div class="footer">
<div class="container"></div>
</div>
app.js
var app = angular.module('plunker', []);
app.controller('HeaderCtrl', function($scope) {
var head = this;
head.logout = logout;
head.loggedIn = 'false';
head.loggedOut = !head.loggedIn;
function logout(){
head.loggedIn ="false";
head.loggedOut = 'true';
}
function logint(){
head.loggedIn ="false";
head.loggedOut = 'true';
}
});
Here is my simply code on Plunker
http://plnkr.co/edit/byNHePeJskAdQbPvFWLp?p=preview
Any solution to manage different header/footer with a loggedIn var ?
Use without ""
try to use as boolean instead of string
like this
head.loggedIn =false;
PLUNKR

AngularJS - trigger same event for included footer and header on all pages

This question have good chance to be a duplicate, but after some searches I wasn't able to find a good explanation to my problem - so I apologize if this is the case.
Well, I got a template which is actually written like this:
<div ng-include="'includes/header.html'"></div>
<section>... Template for homepage, page1, page2... </section>
<div ng-include="'includes/footer.html'"></div>
My header.html is like this:
<section class="header">
<div class="wrapper">
<img id="logotype" src="images/logotype.png">
<ul id="menu">
<li>
Home
</li>
<li class="border-none">
<a class="a" ng-click="chatClicked = !chatClicked">Click to chat</a>
</li>
<li id="logout" class="glyphicon glyphicon-off border-none">
Logout
</li>
</ul>
</div>
</section>
And my footer.html like this:
<section class="footer">
<div class="wrapper">
<ul id="menu-left">
<li>
Home
</li>
<li>
<a class="a" ng-click="chatClicked = !chatClicked">Click to chat</a>
</li>
</div>
</section>
I was wondering if there is a way to open open/hide this new include on all pages (
<div ng-if="chatClicked" ng-controller='ChatController' ng-include="'includes/popup-chat-to-click.html'"></div>
) each time the event chatCliked is triggered - and if it is possible - where it is the best to place this last div?
Ok problem resolved using this link, sorry:
AngularJS - losing scope when using ng-include
This was a matter of $scope.
I had to add this in my controller:
app.controller('homeController',
['$scope'',
function ($scope) {
$scope.chat = { clicked: false };
}]);
in my main view:
<div ng-include="'includes/header.html'"></div>
<div ng-if="chat.clicked" ng-controller='ChatController' ng-include="'modules/chat/popup-contact.html'"></div>
in my header.html:
<a class="a" ng-click="chat.clicked = !chat.clicked">Contact us</a>

Need to call ng-switch by url or $location

I am trying to use a url to call a tab element. For example, a url like: localhost:9000/widget&view=map will land on the page with the map tab selected and shown the map tab body.
<div class="search-result-tab" ng-init="selectTab='list'">
<ul class="nav tab-header">
<li ng-class="{active: selectTab=='list'}" ng-click="selectTab='list'; changedTab()">
<a href={{listTabURL}}>List</a>
</li>
<li ng-class="{active: selectTab=='map'}" ng-click="selectTab='map'; changedTab()">
<a href={{mapTabURL}}>Map</a>
</li>
</ul>
<div class="tab-body" ng-switch on="selectTab">
<div class="tab-content" ng-switch-when="list">
<div ng-include="'list.html'"></div>
</div>
<div class="tab-content" ng-switch-when="map">
<div ng-include="'map.html'"></div>
</div>
</div>
</div>
Other urls are:
list: localhost:9000/widget&view=list
map: localhost:9000/widget&view=map
Similar question here. One suggestion is to inject the $location service and switch on $location.path, might be worth a try if you are not going to try ui-router (which you really should look into!)
function Ctrl($scope, $location) {
$scope.pagename = function() { return $location.path(); };
};
<div id="header">
<div ng-switch on="pagename()">
<div ng-switch-when="/home">Welcome!</div>
<div ng-switch-when="/product-list">Our products</div>
<div ng-switch-when="/contact">Contact us</div>
</div>
</div>

ngController method called twice

I've got an angularjs app with a nav bar inside my index.html page like that :
<div class="navbar navbar-inverse navbar-fixed-top" ng-controller="NavCtrl">
<div class="navbar-inner">
<div class="container">
<ul class="nav">
<li>
Home
</li>
<li>
Add a contact
</li>
<li>
Users
</li>
<li>
Agencies
</li>
<li>
<a ng-click="intro()">Help</a>
</li>
</ul>
</div>
</div>
</div>
This div use a controller, and when i click on the help link it calls the intro method of my controller. But this method is called twice each time !!
This is my controller :
'use strict';
angular.module('myApp')
.controller('NavCtrl', function ($scope, $location) {
$scope.intro = function(){
if($location.path() != '/'){
toastr.warning("Warning.");
}else{
introJs().start();
}
}
});
Any idea ?..
This is the complete html :
<div class="navbar navbar-inverse navbar-fixed-top" ng-controller="NavCtrl">
<div class="navbar-inner">
<div class="container">
<ul class="nav">
<li ng-class="navClass('')">
Home
</li>
<li ng-class="navClass('add')">
Add a contact
</li>
<li ng-class="navClass('users')">
Users
</li>
<li ng-class="navClass('agencies')">
Agencies
</li>
<li>
<a ng-click="intro()">Help</a>
</li>
</ul>
</div>
</div>
</div>
<div class="show-grid"></div>
<div class="container">
<div class="row" ng-view></div>
</div>
Resolved :
Someone (on my project) has added an angular.min script file ... We' have already the angular file for develoment ...
Two angular core library no conflict just methods called twice of course ...
Really my bad sorry guys thx for ur replies

Resources