Unwanted homepage refresh with Angular, does not happen with other pages - javascript

When I navigate to the home/index page via the "Home" link, the page in SPA-style correctly switches the content initially, but then half-a-second later the page refreshes. This does not happen when I navigate to my "Second" page via the same navbar, only when navigating from my Second page to home.
I'm new to Angular so my apologies if I'm missing something blatantly obvious. I've also included my local server code as I'm wondering if that may be the source of the problem...
index.html
<!DOCTYPE html>
<html lang="en-us" ng-app="myApp">
<head>
<title>Intro to Angular</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.0/angular-route.min.js"></script>
<script src="app.js"></script>
<style>
html, body, input, select, textarea
{
font-size: 1.05em !important;
}
</style>
</head>
<body>
<header>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">jQuery</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><i></i> Home</li>
<li><i></i> Second</li>
</ul>
</div>
</nav>
</header>
<div class="container">
<div ng-view>
</div>
</div>
</body>
</html>
main.html
<h1>This is main.</h1>
<h3>Scope value: {{ name }}</h3>
second.html
<h1>This is second.</h1>
<h3>Scope route value (on second page): {{ num }}</h3>
app.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'pages/main.html',
controller: 'mainController'
})
.when('/second/', {
templateUrl: 'pages/second.html',
controller: 'secondController'
})
.when('/second/:num', {
templateUrl: 'pages/second.html',
controller: 'secondController'
})
});
myApp.controller('mainController', ['$scope', '$log', function($scope, $log) {
$scope.name = "Main";
}]);
myApp.controller('secondController', ['$scope', '$log', '$routeParams', function($scope, $log, $routeParams) {
$scope.num = $routeParams.num || 1;
}]);
server.js
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname)).listen(8080, function(){
console.log('Server running on 8080...');
});

Your home link is a standard link to /index.html. Links using angular-route should start with a hash (#) to prevent the browser from navigating away from the page. The solution in this case is to use #/ instead of /index.html

Related

Register controllers and services angular js?

I'm starting to configure my application with Angularjs, I am following a route guide but I can not make the project run
i dont know how to register my controllers and services for load
dynamically when i change pages... :/ y created mi appConfig file for configure my routes.
My directory.
my app config:
angular.module('library.crud', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/views/home.html'
})
.when('/book', {
templateUrl: 'app/views/book.html',
controller: 'bookController',
controllerAs: 'vm'
})
.when('/books', {
templateUrl: '../app/views/books.html',
controller: 'booksController',
controllerAs: 'vm'
})
.otherwise({
redirectTo: '/'
});
});
example controller:
(function () {
'use stritct';
angular
.module('library.crud')
.controller('booksController', booksController);
booksController.inject = ['$rootScope', '$scope', 'bookService'];
function booksController($rootScope, $scope, bookService) {
var vm = this;
}
})();
example service:
(function () {
'use strict';
angular
.module('library.crud', [])
.factory('bookService', bookService);
bookService.$inject = ['$http', '$q'];
function bookService($http, $q) {
var service = {
};
return service;
}
})();
indexHTML:
<html>
<head>
<!--script imports, angular, jquery, bootstrap etc... -->
<script src="app/appConfig.js"></script>
</head>
<body ng-app="library.crud">
<li class="active">Home</li>
<li>Home</li>
<li>Books</li>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
at what time do my HTML pages know which controller to invoke and where is it located? how register my services ?
When i enter a books options from menu, the console show the next error:
The controller with the name 'booksController' is not registered.
UPDATED INDEX.HTML:
<html>
<head>
<link rel ="stylesheet" href="resources/bootstrap/css/bootstrap.min.css"/>
<script src="resources/jquery/jquery.min.js"></script>
<script src="resources/bootstrap/js/bootstrap.min.js"></script>
<script src="resources/angular/angular.min.js"></script>
<script src="resources/angular/angular-route/angular-route.min.js"></script>
<script src="app/appConfig.js"></script>
<script src="app/services/book.service.js"></script>
<script src="app/views/controllers/books.controller.js"></script>
<script src="app/views/controllers/book.controller.js"></script>
</head>
<body ng-app="library.crud">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>Home</li>
<li>Books</li>
</ul>
</div>
</nav>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
There are two things in your code,
(i) You dont have to add dependencies in your code.
angular.module('library.crud').factory('bookService', bookService);
(ii) Add reference for your controller and service in your index.html.
<script src="app/appConfig.js"></script>
<script src="app/service.js"></script>
<script src="app/controller.js"></script>
The main reason this error occurs when everything else looks ok is because you did not include your js files in your index.html. Based on your screenshot, it looks like you have your controllers and services in separate files. Make sure you put them after your appConfig.js file in index.html.
Another issue I see is in your service file.
angular
.module('library.crud', [])
.factory('bookService', bookService);
should be
angular
.module('library.crud')
.factory('bookService', bookService);
If you include square brackets as a second parameter in the .module line, angular will think you are creating a new app instead of trying to register your service/controller to your existing app.
Also, it is highly recommend to use ui-router instead of NgRoute in any Angular1.x applications: https://github.com/angular-ui/ui-router

Template is not rendering data from angular controllers

I have constructed the following routes in angular.
ROUTES
var app = angular.module("app",['ngRoute']);
app.config([
'$routeProvider', '$locationProvider',
function($routeProvider,$locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/items/', {
templateUrl: '/app/items/index.html',
controller: 'ItemsController'
})
.when('/', {
templateUrl: '/app/home/index.html',
controller: 'HomeController'
})
}
]);
Each route has its own template and a controller.
TEMPLATES
items/index.html
<h2>Items</h2>
<div ng-repeat ="item in items">
{{item}}
</div>
home/index.html
<h2>Home</h2>
<p>{{message}}</p>
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Configuration and Routing</title>
<link rel = "stylesheet" href ="bootstrap.min.css">
<base href="/" />
</head>
<body>
<div class ="container">
<h1>Configuration and Routing</h1>
<div class = "navbar">
<ul class ="nav navbar-nav">
<li>Home</li>
<li>Items</li>
</ul>
</div>
<div ng-view>
<h4>{{ message }}</h4>
</div>
</div>
<script src = "angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script src ="./app/app.js"></script>
</body >
</html>
CONTROLLERS
ItemsController
app.controller('ItemsController',[
'$scope',
function($scope) {
$scope.items = ['First','Second','Third']
}
])
HomeController
app.controller('HomeController', [
'$scope',
function($scope) {
$scope.message = 'Welcome!';
}
]);
The problem i have is the browser shows only the partial templates but not the data(i.e 'message' and 'items') from the controllers which it is supposed to show under the div with ng-view attribute.I also get the following errors from the browser "Argument 'HomeController' and ItemsController is not a function got undefined".
How can i resolve this ?

routeProvider not redirecting pages

I have tried this several different way and I will all the different ways I have attempting to redirect to a different page but getting a 404 error for all of them.
index.html
This page is fine and the root is rendering:
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please upgrade your browser to improve your experience.</p>
<![endif]-->
<div ng-view></div>
<div>Angular seed app: v<span app-version></span></div>
<!-- In production use:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js"></script>
-->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="components/version/version.js"></script>
<script src="components/version/version-directive.js"></script>
<script src="components/version/interpolate-filter.js"></script>
<script src="controllers/app.controller.js"></script>
<script src="app.config.js"></script>
</body>
</html>
app.config
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/',{
templateUrl: 'views/templates/home.tpl.html', //page is rendering
controller: 'HomeController'
})
.when('/userForm',{
templateUrl: 'views/templates/userForm.html', //NOT rendering
controller: 'FormController'
})
.otherwise({redirectTo: '/'});
}]);
app.controller.js
app.controller('HomeController',['$scope', 'ROOT', function($scope, ROOT){
$scope.Root = ROOT;
console.log("Inside the home controller");
$scope.menu = {
items:[
{
link: ROOT+'/userForm',
name: 'Contact Form'
}
]
}
}]);
app.controller('FormController',['$scope', function($scope){
console.log("You are inside the form controller");
}]);
Attempting to redirect to userForm.html with a button, a href and a link from the controller. All giving me a 404 error.
<div>
<a class="navbar-brand" ng-href="{{ Root }}">Menu</a>
<button type="button" onclick="window.location.href='/userForm.html'">Next page</button>
<a ng-href="/userForm.html">Click here to go to the next page...</a>
<ul class="nav navbar-nav navbar-right">
<li ng-repeat="item in menu.items" class="dropdown" dropdown on-toggle="toggled(open)">
<a ng-href="{{ item.link }}">{{ item.name }}</a>
</li>
</ul>
</div>
app.js
// Declare app level module which depends on views, and components
var app = angular.module('myApp', [
'ngRoute',
'myApp.version'
]);
app.constant('ROOT','/RedirectedControllerDemo/app/views/templates');
File structure:
The problem is that you have to redirect to a url, not to the html.Try href="#/userForm"
I'll move my comment to an answer (which was the first response here), but due to routing in AngluarJS, the routing component does not need the URL to contain name of the file: userFomr.html, but the route instead www.url.com/userForm
Your href should look like this:
<a href="#/userForm">
But if you wish to remove the #, you can set your app up to use HTML5 mode:
https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag

Angular.js - show link depending on view

I would like to have a link back to the landing page in the header of my app's views but obviously not on the landing page itself. How would I optimally implement that in Angular.js?
Should I use $location.url() to determine the view or should I use bind-html or something else altogether?
Thanks for some tips and help!
EDIT
my current code, I thought I'd made it a little easier since each view has its own controller, however the link is always shown:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<style>
</style>
</head>
<body ng-app="myApp">
<div data-role="page" id="pageone">
<div data-role="header">
<h1>WELCOME!</h1>
BACK TO HOME
</div>
<div ng-view></div>
<div data-role="footer">
<h1>footer</h1>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.min.js"></script>
<script>
'use strict';
var app = angular.module('myApp', ['ngRoute']);
app.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
$routeProvider
.when('/', {
templateUrl : 'views/home.html',
controller : 'HomeController'
})
.when('/other', {
templateUrl : 'views/other.html',
controller : 'OtherController'
});
});
app.controller('HomeController', function($scope, $http, $location, $route) {
$scope.isLandingPage = true;
});
app.controller('OtherController', function($scope, $route) {
$scope.info = 'Other';
});
</script>
</body>
</html>
The link is always shown because your div in which is link doesn't have any controller attached.
You can do it this way:
app.controller('landingPageCtrl', ['$scope', '$location', function($scope, $location){
$scope.isLandingPage = function(){
return ($location.url() == '/home') ? true : false;
}
}]);
then use ng-show to hide or show link depending on location
<div ng-controller="landingPageCtrl" data-role="header">
<h1>WELCOME!</h1>
BACK TO HOME
</div>
I like to check for my route (or state in ui.router).
$scope.isLandingPage = $state.current.name === 'home';
and use <a ng-show="!isLandingPage">Link</a>

Angular template not loading / routes

I'm learning angular and i'm having an issue with displaying my partial.
It's probably something trivial that i forgot but i can't seem to find it.
index.html
<!DOCTYPE html>
<html ng-app="myTool">
<head>
<link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular-route.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="tool-controller.js"></script>
</head>
<body>
<div class="container">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#"><img alt="myTool" src="/templogo.png"></a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a ng-href="#/dashboard">DashBoard</a></li>
<li><a ng-href="#/new">New</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a ng-href="#">Logout </a> </li>
</ul>
</div>
</div>
</nav>
<div ng-view>
</div>
</div>
</body>
</html>
app.js
angular.module('myTool',['ngRoute'])
.config(function($routeProvider){
$routeProvider.when('/new', {
templateUrl: '/tool-new.html',
controller:'ToolController',
controllerAs: "tool"
})
.when('/dashboard', {
templateUrl: '/empty.html'
})
.when('/', {
templateUrl: '/index.html'
})
.otherwise({ redirectTo: '/' });
});
tool-controller.js
angular.module('myTool', [])
.controller('ToolController',['$scope', function($scope) {
$scope.list = [];
$scope.tool = {};
$scope.submit = function() {
$scope.list.push(this.tool);
$scope.succes = 'sent';
};
$scope.search = function() {
};
}]);
and my partial are in tool-new.html and empty.html.
I don't really see what i'm missing :
-index.html as layout with ng-view as placeholder for my partial
basic routes + fall back
my controller linked to my template
html files as my templates with random stuff inside.
im running everything on a local webserv
I've tried adding the controller as a dependency as written in the angulardoc , i've also tried specifically calling the templates in script tags in between my ng-show tags.
Thanks for the suggestions.
Try adding your views like this(just remove '/' at the beginning of the view name):
angular.module('myTool',['ngRoute'])
.config(function($routeProvider){
$routeProvider.when('/new', {
templateUrl: 'tool-new.html',
controller:'ToolController',
controllerAs: "tool"
})
.when('/dashboard', {
templateUrl: 'empty.html'
})
.when('/', {
templateUrl: 'index.html'
})
.otherwise({ redirectTo: '/' });
});
And also remove [] from tool-controller.js
angular.module('myTool')
.controller('ToolController',['$scope', function($scope) {
$scope.list = [];
$scope.tool = {};
$scope.submit = function() {
$scope.list.push(this.tool);
$scope.succes = 'sent';
};
$scope.search = function() {
};
}]);
You are missing the name of the controller in the html i.e. toolController also switch to javascript naming convention of your files it will become easier for you to code.Your actual code in the html should have ng-controller="toolController" which should be placed on your div tag in order to load the controller.

Categories