Angular JS and Dynamic Routing Issues - javascript

I am trying to build a basic dynamic website using Django + AngularJS but I cant for the life of me seem to get dynamic routing working. My HTML is,
<html data-ng-app="homeApp">
<body data-ng-app="homeController">
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<i class="fa fa-dashboard fa-fw"></i> Home
</li>
<li>
<i class="fa fa-bar-chart-o fa-fw"></i> second<span class="fa arrow"></span>
<div id="page-wrapper">
<div data-ng-view></div>
</div>
And my Javascript file.
var homeApp = angular.module('homeApp', ['ngRoute']);
homeApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'home.html',
controller: 'homeController'
}).
when('/second', {
templateUrl: 'home.html',
controller: 'testController'
});
}]);
homeApp.controller('homeController', function($scope) {
});
homeApp.controller('testController', function($scope) {
});
But nothing loads when I click my navigation buttons

Can you tell which browser you are using? This problem may occur in Chrome.
Your code might looks ok.
Remove ngRoute from following line.
var homeApp = angular.module('homeApp', []);
If you run this in firefox, Then your problem might be solved.
Thanks

Related

Routing Angular JS Not Working and not throwing error

I tried to use $routeProvider. But something wrong and i dont know what. Console not throwing error and nothing happen in my page. Im confused. Any solution for me ?
This my code :
var app = angular.module("admin-rv-app", ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'templates/home.html',
controller : 'homeController'
})
// route for the thread page
.when('/thread', {
templateUrl : 'templates/thread.html',
controller : 'threadController'
});
});
app.controller('homeController', function($scope) {
$scope.message = "Welcome Home";
});
app.controller('threadController', function($scope) {
$scope.message = "Welcome to Thread";
});
This is my HTML
<li>
<a href="#">
<i class="fa fa-home fa-3x" aria-hidden="true"></i>
<span class="title">Home</span>
<span class="selected"></span>
</a>
</li>
<li>
<a href="#thread">
<i class="fa fa-briefcase fa-3x" aria-hidden="true"></i>
<span class="title">Thread + Answer</span>
<span class="selected"></span>
</a>
</li>
By the way I have include angular.min.js and angular.route.min.js and ng-app="admin-rv-app"
I think the problem is how you create your app.config.
app.config(["$routeProvider", function($routeProvider){
$routeProvider.when('/', {
templateUrl : 'templates/home.html',
controller : 'homeController'
})
// route for the thread page
.when('/thread', {
templateUrl : 'templates/thread.html',
controller : 'threadController'
});
}])
Try this out instead, and dont add $scope to the module, that will only give you more errors to handle.
Also change the tag, to "/thread" instead of #.
You need to use $routeProvider for the .when statement, otherwise angular cant user the $routeProvider for your diffrent views
Inject $location service in your controller
after that
<a ng-click="changeLocation()"/>
and
$scope.changeLocation = function (){
$location.path('/thread')
}
try using this in HTML:
<li>
<a href="#home">
<i class="fa fa-home fa-3x" aria-hidden="true"></i>
<span class="title">Home</span>
<span class="selected"></span>
</a>
</li>
<li>
<a href="#thread">
<i class="fa fa-briefcase fa-3x" aria-hidden="true"></i>
<span class="title">Thread + Answer</span>
<span class="selected"></span>
</a>
</li>
And change the router code to this:
app.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/home', {
templateUrl: 'app/dashboard/home.html',
controller: 'homeController'
})
// route for the thread page
.when('/thread', {
templateUrl : 'templates/thread.html',
controller : 'threadController'
});
});
If you notice I have changed the URL from "/" to "/home"
and I checked, it is working. Let me if it's not working at your end

Angular ui.router Reload Template

First of all, I'm sorry for a long question, but it just has to be like that. Unfortunately...
I have a couple of templates and a couple of routing logic, all linked in separate files. For some reason the template I want to load (which depends on the region selected), doesn't load its region template. It loads, if I click it second time. Please note I have tried ever solution from this topic:
Reloading current state - refresh data
Nothing worked for me.
I have managed to resolve one (another region) of them by placing "{reload:true}" inline in the html code, like this:
<a data-ui-sref="uk-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
Now I did the same for another template and it is not working. This is my html:
<div class="btn us-btn" data-ng-controller="carCtrlUs">
<script type="text/ng-template" id="careersTplUs.html">
<div class="closer">
<span class="close-me" data-ng-click="ok()">X</span>
</div>
<uib-accordion close-others="true">
<div uib-accordion-group class="modal-body modone panel-default pull-right" is-open="false">
<uib-accordion-heading>
<p class="car-heading">Sales Department <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</p>
</uib-accordion-heading>
<ul>
<li><a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a></li>
<li><a data-ui-sref="us-crm" data-ui-sref-opts="{reload:true}">Client Relationship Manager</a></li>
</ul>
</div>
<div class="modal-body modtwo panel-default pull-right" uib-accordion-group is-open="false">
<uib-accordion-heading>
<p class="car-heading">Marketing Department <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</p>
</uib-accordion-heading>
<ul>
<li><a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Web Developer</a></li>
<li><a data-ui-sref="us-crm" data-ui-sref-opts="{reload:true}">Marketing Coordinator</a></li>
</ul>
</div>
</uib-accordion>
<div class="show-me" ui-view></div>
</script>
<button class="btn" ng-click="open()" data-ui-sref="us-intro">United States</button>
</div>
app.js:
var app = angular.module('carApp', ['ngAnimate', 'ngSanitize', 'ui.bootstrap', 'ui.router']);
controller, for this template:
app.controller('carCtrlUs', function($scope, $http, $uibModal) {
$http.get('json/jobs-us.json').then(function(response) {
$scope.placeholder = response.data.default;
$scope.specs = response.data.specs;
$scope.open = function() {
var modalContent = $uibModal.open({
templateUrl: 'careersTplUs.html',
controller : 'modalContentCtrlUs',
controllerAs: '$ctrl',
size: 'lg',
backdropClass: 'backdropOver',
openedClass: 'modal-opened',
resolve: {
items: function() { return $scope.specs; },
items2: function() { return $scope.placeholder;}
}
})
console.log($scope.placeholder);
console.log($scope.specs);
console.log($scope.specs.web-dev);
}
});
});
app.controller('modalContentCtrlUs', function($scope, $uibModalInstance, items, items2) {
$scope.specs = items;
$scope.placeholder = items2;
$scope.ok = function() {
$uibModalInstance.close();
}
});
factory.js:
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state("us-intro", {
url:"/intro",
templateUrl: "templates/us/start.html"
})
$stateProvider
.state("us-web", {
url: "/web-developer/",
templateUrl: "templates/us/web-developer.html",
})
.state("us-crm", {
url: "/crm/",
templateUrl: "templates/us/crm.html"
})
/*next .state*/
}]);
Template:
<div ng-repeat="(k, v) in specs.webdev">
<h3>{{::v["job-title"]}}</h3>
<p>{{::v["job-body"]}}</p>
United States Apply Here:
<p>{{::v["job-apply"]}}</p>
</div>
As you can see I'm using ui-bootstrap (modal and accordion, since it is all in a modal window).
What can I do to make it refresh instantly? I'm stuck for days on this and it is frustrating... What am I doing wrong here?
EDIT: Please note that I know "::" is for one-way data binding. I've tried without it and the result is the same. I can probably resolve this by placing the data in question in the .json file, but that would really be an ugly hack.
<div ng-repeat="(k, v) in specs.webdev">
<h3>{{::v["job-title"]}}</h3>
<p>{{::v["job-body"]}}</p>
United States Apply Here:
<p>{{::v["job-apply"]}}</p>
</div>
The "::" avoid data binding to reduce digest cycle. Try to remove them.
<a data-ui-sref="uk-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
// it should be
<a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
I have solved this..What I wanted to do is to make the "URL" the same. I have changed the url to manifest the region by the region code, so it is working now.
For example:
UK:
$stateProvider
.state("de-web", {
url: "/web-developer-de",
templateUrl: "templates/de/web-developer.html",
})
.state("de-crm", {
url: "/crm-de",
templateUrl: "templates/de/crm.html"
})
Italy:
$stateProvider
.state("it-web", {
url: "/web-developer-it",
templateUrl: "templates/it/web-developer.html",
})
.state("it-crm", {
url: "/crm-it",
templateUrl: "templates/it/crm.html"
})
United States:
$stateProvider
.state("us-web", {
url: "/web-developer-us",
templateUrl: "templates/de/web-developer.html",
})
.state("us-crm", {
url: "/crm-us",
templateUrl: "templates/de/crm.html"
})
Although this works, I'm not happy. How can it be achieved that the templates are being loaded into the same url?

href angularjs not routing

I have defined my href links like this:
<div id="left-menu">
<div class="sub-left-menu scroll">
<ul class="nav nav-list">
<li><div class="left-bg"></div></li>
<li class="time">
<h1 class="animated fadeInLeft">21:00</h1>
<p class="animated fadeInRight">Sat,October 1st 2029</p>
</li>
<li class="active ripple">
<a href="#hosts">
<span class="fa-home fa"></span> Dashboard
</a>
</li>
<li class="ripple">
<a href="hosts/hosts.html">
<span class="fa fa-calendar-o"></span> Calendar
</a>
</li>
</ul>
</div>
</div>
However when I click on the <a> tags it does not seem to pull back the content held within the my hosts.html file. The url in the browser also does not change with the base url being http://localhost/dashboard/#/main and when I click host the desired output should be http://localhost/dashboard/#/hosts with the correct content displaying. Here is the theme pack I am using http://akivaron.github.io/miminium/
Here are my angularjs files starting with the app itself 'dashApp'
'use strict'
// Declare app level module which depends on views, and components
angular.module('dashApp', [
'ngRoute',
'dashApp.main',
'dashApp.hosts'
])
.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.otherwise({redirectTo: '/main'});
}]);
here is my main:
'use strict'
angular.module('dashApp.main', ['ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider.when('/main', {
templateUrl: 'main/main.html',
controller: 'mainController'
})
}])
.controller('mainController', function($scope, $http, $window){
});
and here is my hosts file:
'use strict'
angular.module('dashApp.hosts', ['ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider.when('/hosts', {
templateUrl: 'hosts/hosts.html',
controller: 'hostsController'
})
}])
.controller('hostsController', function($scope, $http, $window){
});
and here is the project structure:
https://gyazo.com/fb5e2a2651fe8cc460fde783237ddd9c
Remove the trailing / in the href's. They need to match the url in your routing config
Example
<a class="tree-toggle nav-header" href="#/main/" target="_self">
Should be
<a class="tree-toggle nav-header" href="#/main" >
"Href" links should be inside ng-app and ng-view also inside the app. Like Below
<div ng-app="myApp" ng-controller="myController">
home
books
<div ng-view></div>
</div>
first of all check the above then update your js file like below:-
var app=angular.module("myApp",['ngRoute']);
app.config('$routeProvider',function($routeProvider){
$routeProvider
.when('/home',{
templateUrl:'path/some.html'
})
});
feel free to ask if any doubt.
I think you should remove the hash.
<a class="tree-toggle nav-header" href="/main">link</a>

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.

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.

Categories

Resources