AngularJS variables not resolving/displaying - javascript

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}}

Related

ngHide directive only works with ngRoute module after page refresh

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.

How do i define routing to navigate to details page when link clicked

I need some help to implement list and details page.
I have motorList.html page where i am listing all motors as hyperlink retrieved from server (database).
motorList.html
<div>
<ul class="phones">
<li ng-repeat="motor in motors" >
<a href="#/motors/{{motor.Id}}">{{motor.Name}}
</li>
</ul>
</div>
I want when user clicks on any motor link, system should navigate to motorDetails.html page and show the details for clicked/selected motor.
For this i defined my routes as following in app.js
app.js
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/motors', {
templateUrl: 'View/motorlist.html',
controller: 'motorController'
}).
when('/motors/:motorId', {
templateUrl: 'View/motordetail.html',
controller: 'motorDetailsController'
}).
otherwise({
redirectTo: '/motors'
});
}]);
motorDetails.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div>
<ul class="phones">
<li ng-repeat="motor in motors" class="thumbnail">
<p>{{motor.Name}} {{motor.Make}} {{motor.Model}} {{motor.Year}} {{motor.Kilometers}} {{motor.Price}} {{motor.Color}} {{motor.SellerType}}</p>
</li>
</ul>
</div>
</body>
</html>
motorDetailsController.js
var app = angular.module('myApp', ['ngSanitize', 'ui.select']);
app.controller('motorDetailsController', function ($scope, $routeParams, motorService) {
$scope.motors = null;
$scope.getMotorDetails = function (Id) {
motorService.getByMake(Id)
.success(function (motors) {
$scope.motors = motors;
})
.error(function (error) {
$scope.status = 'Unable to load motor data: ' + error.message;
});
}
});
Problem:
When i click on any motor hyperlink, it does not navigate to motorDetails.html page but url changes e.g. http://localhost:12270/View/motorList.html#/motors/161.
I am new to AngularJs routing and for sure i am missing something here but not sure what is wrong.
Could anyone guide me please.
Thanks
You should add ng-view directive on your page, which will show the template loaded from the $routeProvider by watching the URL. You need to add ng-view directive somewhere in your body.
Additionally you should incorporate the changes suggested by #Dvir.
Markup
<body>
<div>
<ul class="phones">
<li ng-repeat="motor in motors" class="thumbnail">
<p>{{motor.Name}} {{motor.Make}} {{motor.Model}} {{motor.Year}} {{motor.Kilometers}} {{motor.Price}} {{motor.Color}} {{motor.SellerType}}</p>
</li>
</ul>
</div>
<div ng-view></div>
</body>
Update
Ideally you should have ng-view directive there in motorList.html, which gets loaded(But I'm treating it as the index.html page where all the css & js references are there)
Also you don't need to include the html, head & body tag in partial as its going to treated as partial, So remove body,head & html tag and make it simple by placing required template only.
motorDetails.html
<div>
<ul class="phones">
<li ng-repeat="motor in motors" class="thumbnail">
<p>{{motor.Name}} {{motor.Make}} {{motor.Model}} {{motor.Year}} {{motor.Kilometers}} {{motor.Price}} {{motor.Color}} {{motor.SellerType}}</p>
</li>
</ul>
</div>
That's because href is a regular attribute and it's not evaluated by angularJs.
To make this expression to be your desired link you have to use ng-href so angularJs will evaulate the expression and assign it to an href html attirbute.
You have to change
href="#/motors/{{motor.Id}}"
to
ng-href="#/motors/{{motor.Id}}"
In addition to get its id. you have to use $routeParams in the controller.
For instance:
var id = $routeParams.motorId
UPDATE
I missed that but #Pankaj Parkar right. You have to use ng-view to make the routeProvider to assign the relevant view to the right placeholder.
How to use ng-view ?
You have to make an element where do you want to make the view appear.
It can be part of the page or all the page.
Put the element wherever you want and you'll understand.
For instance:
<body>
<div id="nav">
</div>
<ng-view>
<!-- this is the place your html template will apear -->
</ng-view>
</body>

update variable in another controller in AngularJS

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>

Template not loading in Angular route

Issue is quite simple. I have been trying for hours now but just couldn't get the template to load via angularJS client side routing. Not using any server side routing.
So, used various combinations of paths. If I use "/home" in button href it straight away gives error that it couldn't find "/home". But with "#/home", I don't get that error but it still wouldn't load the template.
Any help would be greatly appreciated.
Created a new plunker: http://plnkr.co/edit/F7KoWbBuwsXOQLRPF0CN?p=preview
Template directory:
Project ---
|
|
CSS
|
|
JS
|
|
templates---
|
|
home.html
JS:
var myApp = angular.module("myApp",['ngRoute']);
myApp.controller('appController',function($scope,$http){
//mytext = 0; instantiating variables without using var gives referencing error due to "use strict";
$scope.angular = angular;
$scope.mytext = "Harsh";
$scope.formSuccess = false;
$http({method:"GET", url:"JS/carousel-data.json"}).
success(function(data) {
$scope.carouselData = angular.fromJson(data);
}).
error(function(data) {
console.log("Error loading images");
});
myApp.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/home', {
templateUrl: 'templates/home.html',
controller: 'appController'
})
.when('/edit', {
templateUrl: 'templates/home.html',
controller: 'appController'
});
});
HTML:
<body ng-controller="appController">
<header id="pageHeader" class="col-md-12 col-sm-12 col-xs-12 header">
<nav class="col-md-5 col-sm-6 col-xs-10 menu">
<ul class="nav nav-pills" id="menuLinks">
<li class="dropdown visible-xs">
Sapient <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>Home</li>
<li>Edit</li>
</ul>
</li>
<li role="presentation" class="hidden-xs" >Home</li>
<li role="presentation" class="hidden-xs" >Edit</li>
</ul>
</nav>
</header>
<div ng-view></div>
</body>
It's rather unclear how you've set up things? Is the HTML your index or is that your home.html?
Secondly you already declare the controllers of your pages to be appController, no need to define that with the ng-controller directive anymore.
Apart from that you're loading the same template on each href, could it be that you're just seeing the same page like declared?
$routeProvider
.when('/home', {
templateUrl: 'templates/home.html', <---
controller: 'appController' <---
})
.when('/edit', {
templateUrl: 'templates/home.html', <---
controller: '**appController'<--
});
It should be noteworthy that there is a more extensive module for routing. You can find it at ui-router.

`ng-class` not working on functional call from included template

I have my main template called home.html, the controller is homeController applied throw :
$routeProvider :
$routeProvider
.when ("/", {
templateUrl : "views/home.html",
controller : "homeController"
});
$routeProvider
.otherwise ({
redirectTo:'/'
});
works fine. I have seperate html template for header' which included in thehome.html` like this:
<div class="content">
<ng-include src="'/views/header.html'"></ng-include>
<div class="globe">
<div class="progName">
<div class="swiper"></div>
<h2 class="active">
<span class="title">
{{activeApp.name}}
</span>
<span class="note">{{activeApp.note}}</span>
</h2>
<h2 class="que t{{$index+1}}" ng-click="activate(app)" ng-repeat="app in queApp">{{app.name}}</h2>
</div>
for the header i have seperate controller called 'header.jswhich is included in theindex.html` file.
<script src="app.js"></script>
<script src="js/script/factory/server.js"></script>
<script src="js/script/controllers/header.js"></script>
<script src="js/script/controllers/homeController.js"></script>
<script src="js/script/directives/home/programNames.js"></script>
In the header, there is a class, i want to apply by conditionally, so i added the condition in the header.html file (which is included)
in the header.js (headerController) I am trying to add the conditonal class, but not working:
my header.js:
angular.module("tcpApp")
.controller('header', ['$scope', function ($scope) {
$scope.show = false;
$scope.menuHandler = function () {
$scope.show = !$scope.show;
console.log("i am called");
}
}]);
What i am missing here? the way i am adding the controller is wrong? or i need to write the function withing parent controller homeController itself?
can't I keep seperate controller for header and include with other template?
Andy one help me handle?
Thanks in advance.
UPDATE
Header html :
<header ng-controller="header" >
<h1>TCP</h1>
<nav>
<a class="menu" ng-click="menuHandler()" href="#">Menu</a>
<span ng-class="{'activate':show}">
<span>All</span>
<span>Important</span>
<span>Design</span>
<span>Supply</span>
<span>Contruction</span>
<span>Issue Log</span>
</span>
</nav>
</header>
Try something like this in your home.html :
<div class="content">
<ng-include src="views/header.html"></ng-include>
//code here
</div>
Remove the '/' at the starting of the path of header.html template.
This should do the trick, I guess.
try something like this:
<span ng-class="show?'activate':'other-class'">
the problem is, I am using a module for scroll purpose. when i comment that, it works.
var newHash = 'anchor3';
if ($location.hash() !== newHash) {
$location.hash('anchor3');
} else {
$anchorScroll();
}
I commented all above. thanks every one!

Categories

Resources