okay, so I am building a web-app using angular.js. I have started to implement user authentication.
I did this with it's own controller:
app.controller("userControl", ["$http", "share", function($http, share){
this.login = {};
var user = this;
this.doLogin = function(){
this.login.fn = "login";
$http.post('classes/main.php', user.login).success(function(data){
console.log(data.Error);
if(data.Error == undefined){
alert("Success");
share.user = data;
window.location.href = "#memberHome";
}
});
}
}]);
and I have a member's page with it's own controller:
HTML:
<div id="memberHome" data-role="page" ng-controller="member-Ctrl as member">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<p class="navbar-brand" href="#">Calendar</p>
</div>
<ul class="nav navbar-nav navbar-left">
<li>Overview</li>
<li>Friends</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><span class="glyphicon glyphicon-user"></span> Logged in as: {{member.user.forename + " " + member.user.surname}}</li>
<li><span class="glyphicon glyphicon-log-in"></span> Log Out</li>
</ul>
</div>
</nav>
<div data-role="content">
<calendar selected="day"></calendar>
</div>
</div>
javascript:
app.controller("member-Ctrl", ["share", function(share){
this.user=share.user;
}]);
I need the User controller to tell the member controller the details of the new user.
I googled this and looked at the answers of a similar question, which led me to This
and i created a service as shown in the video:
app.service("share", function(){
this.user = {}
});
Now whenever i login and get redirected to the memberHome page, it tells me Logged in as:
Can anybody see why this might be?
I am very new to Angular, and am learning, just about, everything when I need it.
I should probably say that i am using jQuery Mobile (for a multi-page document) and Bootstrap 3
You can use a service to share information between controllers or use the $rootScope
var app = angular.module('mymodule',[]);
app.controller('Controller1', ['$scope','$rootScope',
function($scope, $rootScope) {
$rootScope.showImages = true;
}]);
app.controller('Controller2', ['$scope','$rootScope',
function($scope, $rootScope) {
$rootScope.showImages = false;
}]);
And in the template:
<div ng-controller="Controller1">
<div class="images" ng-show="$root.showImages"></div>
</div>
Related
I am making a test Web app and I am trying to store my user details in the local storage but Some how, Its not storing in the local Storage which in turn makes my login to fail or there may be any other reason. I am not getting any errors in the console and when I sign up the data is also going into my database.
Code for my Controller:
`(function(){
angular.module('Test')
.controller('loginController',["$scope","$state","$http", function($scope, $state, $http){
if(localStorage['User-Data']) {
$scope.loggedIn = true;
}
else {
$scope.loggedIn = false;`}
$scope.logUserIn = function() {
$http.post('api/users/login', $scope.login).success(function(response){
localStorage.setItem('User-Data', JSON.stringify(response));
$scope.loggedIn = true;
}).error(function(err){
console.log(err);
});
};
$scope.logOut = function() {
localStorage.clear();
$scope.loggedIn = false;
}
}]);
})();
and my Html is as follows:
<nav class="nav navbar-default navbar-fixed-top" ng-controller="loginController">
<div class="container-fluid">
<div ng-show=!loggedIn>
<strong> Email: </strong> <input type="text ng-model="login.email">
<strong> Password: </strong> <input type="password" ng-model="login.password">
<button ng-click="logUserIn()"> Login </button> <a ui-sref="signUp"> Create an Account </a>
</div>
<div ng-show="loggedIn">
<a ui-sref="editProfile"> Edit Profile </a>
<a ui-sref="logOut()"> Logout </a>
</div>
</div>
</nav>
<body>
<div ui-view> </div>
</body>
The problem is not about any syntax error or missing directory. Please look into this code and help me out.
Try to use
JSON.parse(localStorage.getItem('User-Data'))
change your code from
localStorage.setItem('User-Data', JSON.stringify(response));
to
localStorage.setItem('User-Data', JSON.stringify(JSON.parse(response)));
I am a newbie in Angular JS. I am replacing a webapp from jquery and PHP to Angular JS + PHP (PHP is necessary to get data from DB and pass it on JSON).
The PHP module works, I have tested. My problem is on AngularJS.
This is index.html
<body ng-app="manager">
<div class="container">
<nav class="navbar navbar-default">
<div class="container-fluid" ng-controller="managerController as menuManager">
<div class="navbar-header">
<a class="navbar-brand" href="#">Manager</a>
</div>
<ul class="nav navbar-nav">
<li class="active" ng-repeat="voce in menuManager.voce">{{voce.nome}}</li>
</ul>
</div>
</nav>
<div ng-view></div>
</div>
</body>
This is manager.js
var app = angular.module('manager', ['ngRoute']);
app.config(['$routeProvider',
function($routeProvider){
$routeProvider
.when("/a",{templateUrl:"a.html",controller:"aCtrl"})
.when("/b",{templateUrl:"b.html",controller:"bCtrl"})
.when("/c",{templateUrl:"c.html",controller:"cCtrl"})
.when("/d",{templateUrl:"d.html",controller:"dCtrl"}); }]);
app.controller('managerController',function(){
this.voce = menu;
});
menu = [
{'nome':'A', 'url':'a'},
{'nome':'B', 'url':'b'},
{'nome':'C', 'url':'c'},
{'nome':'D', 'url':'d'}
];
This is the aCtrl.js
app.controller("aCtrl", function($http,$scope){
$http.post("../../qry_select.php",{"payload":"manager"})
.success(function(data){
alert("Work!");
$scope.content = data;
})
.error(function(){
alert ("Doesn't work");
});
});
and this is the aView.html
<div ng-controller="aCtrl">
<p>{{content}}</p>
</div>
My problems are:
Work alert is showed twice (?)
Content is blank
Firebug shows me just qry_select.php send data, not received data
Please help me
When I login on my app, I want the login and signup button to disappear from the nav so I am using ng-hide directive if the login was successful and a token was received from the server, which I store in the cookies.
Nav is part of the index.html file.
Because I am using angular routing, when login is successful, index.html is not loaded again instead I render the home page through ng-view directive.
The problem is I have to refresh the page for ng-hide to work. I am assuming it is because ng-hide is part of index.html page, which does not get reloaded.
Hoping there is a bette solution than refreshing the page every time someone logs in.
Here is some of my relevant code.
HTML
<!-- Navigation -->
<nav class="navbar navbar-custom navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
<i class="fa fa-bars"></i>
</button>
<a class="navbar-brand page-scroll" href="#/">
<i class="fa fa-play-circle"></i> <span class="light">Webnar</span>
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse navbar-right navbar-main-collapse">
<ul class="nav navbar-nav">
<!-- Hidden li included to remove active class from about link when scrolled up past about section -->
<li class="hidden">
</li>
<li>
<a class="page-scroll" href="#about">Webinars</a>
</li>
<li ng-hide="token">
<a class="page-scroll" href="#/login">Login</a>
</li>
<li ng-show="token">
<a class="page-scroll " href="#/create">Add a webinar</a>
</li>
<li ng-hide="token">
<a class="page-scroll btn btn-default " href="#/signup">Sign Up</a>
</li>
<li ng-show="token" >
<a class="page-scroll btn btn-default" ng-click="logOut()">Logout</a>
</li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
App.js
var webinarApp = angular.module('webinarApp', ['ngCookies', 'ngRoute']);
webinarApp.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: './home.html',
controller: 'mainController'
})
.when('/signup', {
templateUrl: './signup.html',
controller: 'mainController'
})
.when('/login', {
templateUrl: './login.html',
controller: 'mainController'
})
.when('/create', {
templateUrl: './create.html',
controller: 'mainController'
})
});
webinarApp.controller('mainController', ['$scope', '$http', '$cookies', '$location', function($scope, $http, $cookies, $location){
$scope.welcomeMessage = '';
$scope.users = [];
$scope.searchQuery = "";
$scope.orderByField = 'name';
$scope.newUser = {};
$scope.logInUser = {};
$scope.webinars = [];
$scope.newWebinar = {};
$scope.isDisabled = false;
// ============== Users ================
$scope.getUsers = function(){
$http.get('/api/users').then(function(response){
$scope.users = response.data;
});
};
$scope.getUsers();
$scope.createUser = function(){
$http.post('/api/users', $scope.newUser).then(function(response){
console.log(response.data)
$scope.users.push(response.data);
$scope.newUser = {};
$location.path('/login');
});
};
$scope.obtainToken = function(){
$http.post("/api/users/authentication_token", $scope.logInUser).then(function(reponse){
$scope.token = reponse.data.token;
console.log($scope.token);
$cookies.put('token', $scope.token);
$location.path('/')
});
};
It's because you put the navbar on the index page. It's not a template that is loaded by the route module. So it's not related to any route and controller that are bind with it. Controller declared in routes only applies for template that are loaded by the route module.
To bind a controller whatever the route is use ng-controller directive. Put it on your <nav> element
Note if you use the "as controller" syntax you must do in controller :
this.isDisabled
instead of
$scope.isDisabled
Documentation : https://docs.angularjs.org/#!/api/ng/directive/ngController
If you need to update datas to that controller with the rest of the application. Use $rootScope. If you use 'ctrl as' syntax, the easier is to do :
this.$rootScope=$rootScope;
If you don't like this use $watch to watch for changes and rebind the currentValue to the controller :
$rootScope.watch('myParameter', function(new){
this.myParameter = new;
});
AND DON'T FORGET TO INITIALIZE THE VARIABLE IN $ROOTSCOPE. Or the variable will end up in a child scope that won't be visible for your navbar's controller.
You should declare $scope.token with your other variable declarations. It does not exist in the scope when you are initially setting your ng-hide.
$scope.isDisabled = false;
$scope.token;
Have you tried using $scope.$apply() ???
$scope.$apply(function() {
$scope.token = <whatever value>;
})
Ok i think one way to do this would be to add a controller for nav say navbarController.
<nav ng-controller="navbarController">...</nav>
Inject $rootScope into both maincontroller and navbarController.
then in mainController whenever you need to change value of token, do this
$rootScope.$emit('tokenValueChange', <value>);
then in navbarController add,
$rootScope.$on('tokenValueChange', function(newValue) {
$scope.token = newValue;
})
I am not sure if this is a perfect method but this should work.
I had a similar problem as OP (viditsaxena), and solved it the same way he did. Like him, I had ng-hide in my nav which was located in index.html. My ng-hides worked correctly on initial page load, but when I tried to navigate to a different view, my ng-hide's would not work until I refreshed the page.
My solution: The same way #viditsaxena describes in his comments under the accepted answer (use $rootScope instead of $scope), but I thought I'd put my actual code here to show you how I made it work in my app.js file:
I went from this (ng-hide required refresh to load after I navigated away from the original view):
app.controller('routeController', ['$scope', '$location', function($scope, $location) {
$scope.showPortfolioHeader = $location.path() === '/jcRealty';
}]);
To this (now my ng-hides don't require a refresh after I navigate away from my first view):
app.controller('routeController', ['$rootScope', '$location', function($rootScope, $location) {
$rootScope.showPortfolioHeader = $location.path() === '/jcRealty';
}]);
The accepted answer got me part of the way there, but I had a hard time deciphering some of the grammar in his response. My own testing confirmed some of what he said. My controller above (routeController) is related to the view located at the /jcRealty path. If I put my ng-hides in my jcRealty view, they work properly (no refresh needed) using $scope. But since my ng-hide's are on index.html, outside of that controller's path, $rootScope was needed to not require a page reload.
I've an issue with Angular JS. I don't get why my data in the scope can't be displayed with the {{ }} but can be display if I use the directive : data-ng-bind.
If anyone has an idea :
Here's my HTML Code :
<aside id="sidebar-left" class="sidebar-left" data-ng-controller="PortalController" data-ng-init="getAppslist()">
<div class="sidebar-header">
<div class="sidebar-title">
Navigation
</div>
<div class="sidebar-toggle hidden-xs" data-toggle-class="sidebar-left-collapsed" data-target="html" data-fire-event="sidebar-left-toggle">
<i class="fa fa-bars" aria-label="Toggle sidebar"></i>
</div>
</div>
<div class="nano" >
<div class="nano-content">
<nav id="menu" class="nav-main" role="navigation">
<ul class="nav nav-main">
<li class="nav-active">
<a href="#!/">
<i class="fa fa-home" aria-hidden="true"></i>
<span>Dashboard</span>
</a>
</li>
<li>
<a href="#!/users">
<i class="fa fa-users" aria-hidden="true"></i>
<span>Users</span>
</a>
</li>
<li class="nav-parent">
<a href="#!/apps">
<i class="fa fa-cubes" aria-hidden="true"></i>
<span>Apps</span>
</a>
<ul class="nav nav-children">
<li ng-repeat="app in appslist">
<a ng-href="#!/apps/{{app.CloudAppInstanceId}}">{{app.Name}}</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</aside>
Here's my controller :
angular.module('core').controller('PortalController', ['$scope', 'Portal',
function($scope, Portal) {
$scope.getAppslist = function() {
Portal.getApps(function(callback) {
$scope.appslist = callback;
$scope.blabla = 'blabla';
});
};
}]);
And here's my service :
angular.module('core').factory('Portal', function($http, $cookies, $rootScope) {
// define factory object
var factory = {};
var getApps = function(callback){
$http.get($rootScope.logrrApiAddress + '/apps', config).success(function(data, status, headers, config) {
callback(data);
});
}
factory.getApps = function(callback){
return getApps(callback);
}});
Thanks in advance for your response
Martin Taz
You don't need handlebars in an ng-href. Try:
<a ng href="'#!/apps/' + app.CloudAppInstanceId">{{app.Name}}</a>
Better yet would be to turn that into a method on your controller.
<a ng href="'#!/apps/' + app.CloudAppInstanceId">{{app.Name}}</a>
Seems to me that app is not defined in the scope, what you do set in PortalController, though, is $scope.appslist.
Also, the Portal factory function must return an object instance (it currently doesn't return anything). AND the factory's method must actually return a promise, too.
angular.module('core').factory('Portal', [
'$http', '$cookies', '$rootScope',
function($http, $cookies, $rootScope) {
var factory = {}; // define factory object
factory.getApps = function(){
// FIXME: what is "config", where is it supposed to come from?
return $http.get($rootScope.logrrApiAddress + '/apps', config);
};
return factory; // <-- you need to return something
}
]);
angular.module('core').controller('PortalController', [
'$scope', 'Portal',
function($scope, Portal) {
$scope.getAppslist = function() {
Portal.getApps().then(function (data) {
$scope.apps = data;
$scope.blabla = 'blabla';
});
};
}
]);
I changed things a bit, esp. got rid of the callback parameter - you don't need that, simply get the promise that getApps() returns and use the data once the promise is resolved.
Here is the relevant HTML:
<!DOCTYPE html>
<html ng-app="wpApp">
<body>
<div ng-controller="controllerMain as main">
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-left">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</div>
<!-- Start of View State -->
<div class="page-content" style="padding-left:10px; padding-right:10px">
<div ng-view></div>
</div>
<!-- End of View State -->
<div class="footer">
<div class="banner">
{{main.message}}
</div>
</div>
</div>
</body>
</html>
And here is the relevant Javascript
wpApp = angular.module("wpApp", ["ngRoute", "ngAnimate", "ui.bootstrap", "angularFileUpload"]);
wpApp.config(function($routeProvider) {
return $routeProvider.when("/", {
templateUrl: "one.html",
controller: "controllerOne"
}).when("/two", {
templateUrl: "two.html",
controller: "controllerTwo"
}).when("/three", {
templateUrl: "three.html",
controller: "controllerThree"
});
});
wpApp.controller("controllerMain", function() {
this.ready = 'true';
this.message = "This is the Main Controller";
});
});
Now, with everything set up exactly as it is above (with some additional controllers for the other pages and all), controllerMain's message is properly displayed: "This is the Main Controller" in the specified spot within the HTML.
Now, I need an $http call to be made in controllerMain, so I change it like so:
wpApp.controller("controllerMain", function($http) {
this.ready = 'true';
this.message = "This is the Main Controller";
return $http.get("config.json").success(function(data) {
console.log("Here");
});
});
When this happens, I can see "Here" in the log, but nothing is displayed where "{{main.message}}" should be displayed. A little debugging has shown me that basically if the $http GET call is made, nothing is displayed. If I remove the call, the message displays.
What is the problem here? Is it something with the way the program is configured? Am I not understanding something about the way controllers work?
please try to remove the return you don'e need to return anything from the controller
wpApp.controller("controllerMain", function($scope, $http) {
$scope.ready = 'true';
$scope.message = "This is the Main Controller";
$http.get("config.json").success(function(data) {
console.log("Here");
});
});
I also suggest to use $scope.message = "This is the Main Controller";
and on html {{message}}