I am trying to create my first AngularJS app.
But I can not understand why my routing is not working properly(i think there is some problem in my when() method and directory structure).
Here is my directory structure(I have followed AngularJS standard naming convention).
Directoty Structure
-Home
--sidebar
---sidebar.component
---sidebar.template
--home.component
--home.template
--home.module
-menu
--menu.module
--menu-list
---menu-list.component
---menu-list.template
-app.js
app.js
angular.module('myApp', [
'ngRoute',
'menu',
'home'
]).
config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
$routeProvider
.when('/menu-list', {
template: '<menu-list></menu-list>'
})
.when('/home', {
template: '<home></home>'
})
.when('/sidebar', {
template: '<sidebar></sidebar>'
})
.otherwise('/home');
}]);
menu.module.js
angular.module('menu',[]);
menu-list.component.js
angular.module('menu')
.component('menu-list', {
templateUrl: 'menu/menu-list/menu-list.html',
controller: [
function MenuListController() {
alert("MenuListController Called");
}
]
});
Been a long time since I've tried using ngRoute but here's how my 'otherwise' statement differs from yours:
.otherwise({
redirectTo: '/home'
});
The difference is here I pass in an object with the property 'redirectTo'. You can check this article out as well.
The Problem was I did not name component correctly. In angularJS to include the view in html we need to name component in camelCase and it will be included by hyphen-case
Component name: 'phoneList'
View name: '<phone-list></phone-list>'
Example from AngularJS-Tutorial
app/index.html:
<html ng-app="phonecatApp">
<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="app.js"></script>
<script src="phone-list.component.js"></script>
</head>
<body>
<!-- Use a custom component to render a list of phones -->
<phone-list></phone-list>
</body>
</html>
app/phone-list.component.js:
// Register `phoneList` component, along with its associated controller and template
angular.
module('phonecatApp').
component('phoneList', {
template:'phone-list.html',
controller: function PhoneListController() {
//...
}
});
Note:If any error or written badly feel free to Edit
Related
I have a question regarding Angular UI-Router and its ui-views. I declare three ui-views inside another one, and the only one that shows up is the one with the name "languages". I don't understand why this happens, and if anybody could help that would be great.
index.html:
<div ui-view="languages">
<div ui-view="dashboard"></div>
<div ui-view="partners"></div>
<div ui-view="footer"></div>
</div>
routes.js:
angular.module('TMHM')
.config(routeConfig);
routeConfig.$inject = ['$stateProvider', '$urlRouterProvider'];
function routeConfig ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
views: {
'languages': {
templateUrl: 'views/languages/languages.html'
},
'dashboard': {
templateUrl: 'views/dashboard/dashboard.html'
},
'partners': {
templateUrl: 'views/partners/partners.html'
},
'footer': {
templateUrl: 'views/footer/footer.html'
}
}
});
$urlRouterProvider.otherwise('/');
};
Here's the Plunker code, although I couldn't get that to work:
https://plnkr.co/edit/z8cFGHKVQNN623QbBUqi
There is updated and working plunker https://plnkr.co/edit/vKOr2yLUfaAfwoGyK0ws?p=preview
I created new routes.html, with this content
<h1>Routes</h1>
<hr />
<div ui-view="languages"></div>
<div ui-view="dashboard"></div>
<div ui-view="partners"></div>
<div ui-view="footer"></div>
And changed index.html to contain
<div ui-view=""></div>
And then state adjustment is:
.state('home', {
url: '/',
views: {
'': {
templateUrl: 'routes.html'
},
'languages#home': {
templateUrl: 'languages.html'
},
'dashboard#home': {
templateUrl: 'dashboard.html'
},
'partners#home': {
templateUrl: 'partners.html'
},
'footer#home': {
templateUrl: 'footer.html'
}
}
});
Also, essential was move the ng-app from <head> to <html> element
<html ng-app="TMHM">
<head >
check it here
More details and examples about named and multi views:
Nested states or views for layout with leftbar in ui-router?
Angular UI Router - Nested States with multiple layouts
I've never seen that done this way before (a routed view in a routed view). That may be because it doesn't work, or I've just never run into it, I don't know. I tend to think of views as being top level, and then includes as being the nested content.
If that's the idea, I've done something very similar to this, but I used ng-include (I currently have this in production in an app serving a lot of users):
<div ng-include="mycontroller.pathToFileIWantToShow"></div>
// alternatively, although hardcoding can be evil...
<div ng-include="path/to/some/file.html"></div>
This allows me to change the content dynamically, use binding etc. etc, and each included template can reference its own controller, or just use the controller that wraps it. It doesn't seem to matter how many I nest.
I try to show a view with angular paths. the console does not throw any error or warning.
But equally the view is not displayed.
What am I doing wrong?
index.html
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head></head>
<body>
<ng-view></ng-view>
<!-- build:js bower/vendor -->
<script type="text/javascript" src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/angular-route/angular-route.min.js"></script>
<!-- endbuild -->
<script src="./routes.js"></script>
<!-- build:app scripts/js || CUSTOMER -->
<script src="./components/customer/customerService.js"></script>
<script src="./components/customer/customerController.js"></script>
<!-- endbuild-->
</body>
</html>
routes.js
var _templateBase = './components';
angular.module('app', [
'ngRoute'
])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: _templateBase + '/customer/customer.html' ,
controller: 'customerController',
controllerAs: '_ctrl'
})
.otherwise({
redirectTo: '/'
});
}
]);
costomerService.js
angular.module('app', [])
.factory('customerService', function() {
});
costomerController.js
angular.module('app',[])
.controller('customerController', ['$scope', function($scope, customerService) {
//
}]);
It's wrong? Because the view is not displayed? I'm using obsolete mertodos, guide me lleguar many tutorials there.
Thanks so they can help.
This creates your app because you have included the second parameter (an array of dependencies to inject):
angular.module('app', [
'ngRoute'
])
Remove the second parameter on your other angular.module() definitions because that is causing a new app to be created each time.
angular.module('app') <-- no second parameter tells it to use the existing 'app' module
.factory('customerService', function() {
});
angular.module('app') <-- no second parameter tells it to use the existing 'app' module
.controller('customerController', ['$scope', 'customerService', function($scope, customerService) {
//
}]);
I added customerService to your injection array on your controller definition because the array elements have to match up exactly to your function parameters.
Also, if you are using controllerAs syntax as you have done on your route definition then you may not want to inject $scope into your controller.
I am trying to make a single page application while using components since my company will be moving to using components in the future and I am trying to follow the angular-phonecat tutorial. The problem I'm having is that for some reason in my app.config.js file, the template for the home page is not being recognized (the home-page portion) and I can't figure out why. If I replace that with a simple string of 'hello', it displays just fine, so it has to be somewhere in my components but I can't track down why it's not recognizing it.
Relevant code:
app.config.js:
angular.
module('newSpa').
config(['$locationProvider', '$routeProvider',
function config($locationProvider, $routeProvider){
$locationProvider.hashPrefix('!');
$routeProvider.
when('/home',{
template: '<home-page></home-page>'
}).
when('/contacts', {
template:'<contacts></contacts>'
}).
otherwise('/home');
}]);
app.module.js:
angular.module('newSpa', [
'ngRoute',
'homePage',
'contacts'
]);
home-page.template.html:
<div>
<p>{{message}}</p>
</div>
home-page.module.js:
angular.module('homePage', []);
home-page.component.js:
angular.module('homePage').component('homePage', {
templateUrl: 'home-page/home-page.template.html',
controller: 'homeCtrl'
});
controllers.js:
angular.module('homePage', []).controller('homeCtrl', ['$scope', function($scope){
$scope.message = 'hello';
}]);
index.html:
<!DOCTYPE html>
<html lang="en" ng-app="newSpa">
<head>
<meta charset="UTF-8">
<title>SPA Contacts</title>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="app.module.js"></script>
<script src="app.config.js"></script>
<script src="home-page/home.module.js"></script>
<script src="home-page/home.component.js"></script>
<script src="contacts/contacts.module.js"></script>
<script src="contacts/contacts.component.js"></script>
<script src="controllers/controllers.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
My app.config.js file is in the root "app" directory, and my home files are all in the "/app/home-page" directory. Link to angular-phonecat: https://docs.angularjs.org/tutorial/step_03
So my previous solution was still incorrect. The real solution is that my controller was redefining the 'home' module because I had square brackets. Here is the old controller:
angular.module('homePage', []).controller('homeCtrl', ['$scope', function($scope){
$scope.message = 'hello';
}]);
So as you can see, when I have square brackets in the module definition, I am redefining the module, thereby overwriting all previous definitions of the module. When I removed those brackets:
angular.module('homePage').controller('homeCtrl', ['$scope', function($scope){
$scope.message = 'hello';
}]);
Everything displays properly. So the issue was I was making a new module with just the controller, so it didn't have the template to push to the view to update.
You seem to have named your component 'home' but are using 'home-page' in your template.
I'm trying to create a simple website using angular as front-end.
Is there a way to create partial views and routing without having a webserver?
I've been trying to do so, but I keep getting this error:
Uncaught Error: [$injector:modulerr]
Here's my code: index.html
<!DOCTYPE html>
<html lang="en" ng-app="cerrajero">
<head>
<meta charset="UTF-8">
<title>Cerrajero</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
</head>
<body ng-controller="MainCtrl">
<div ng-view></div>
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="js/angular-route.min.js"></script>
<script src="js/app.js"></script>
<script type="text/ng-template" id="partials/contact.html" src="partials/contact.html"></script>
<script type="text/ng-template" id="partials/services.html" src="partials/services.html"></script>
<script type="text/ng-template" id="partials/home.html" src="partials/home.html"></script>
</body>
</html>
and the app.js:
var app = angular.module('cerrajero', []);
app.config([function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when('/services', {
template: 'partials/services.html'
}).
when('/contact', {
template: 'partials/contact.html'
}).
when('/home', {
template: 'partials/home.html'
}).
otherwise({
redirectTo: '/home',
template: 'partials/home.html'
});
}]);
function MainCtrl ($scope) {
};
What am I doing wrong?
edit
I've added the ngRoute but I still get the same error when I open the index.html file in the browser.
var app = angular.module('cerrajero', ['ngRoute']);
app.config([function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when('/services', {
template: 'partials/services.html'
}).
when('/contact', {
template: 'partials/contact.html'
}).
when('/home', {
template: 'partials/home.html'
}).
otherwise({
redirectTo: '/home',
template: 'partials/home.html'
});
}]);
function MainCtrl ($scope) {
};
edit 2
Here's the files on github:
https://github.com/jsantana90/cerrajero
and here's the website when it loads:
http://jsantana90.github.io/cerrajero/
edit 3
I've manage to get rid of the error by having the following code:
var app = angular.module('cerrajero', ['ngRoute']);
app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode(false);
$routeProvider.
when('/services', {
template: 'partials/services.html'
}).
when('/contact', {
template: 'partials/contact.html'
}).
when('/home', {
template: 'partials/home.html'
}).
otherwise({
redirectTo: '/home',
template: 'partials/home.html'
});
}]);
app.controller('MainCtrl', function ($scope) {
});
I added this app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
But now my page is blank. It doesn't redirects or anything.
Have I placed everything how it's suppose to go?
edit 4
I forgot to change ui-view to ng-view. Now it works but it's showing in the view: partials/home.html instead of the actual view.
edit 5
Ok so, after having this final code:
var app = angular.module('cerrajero', ['ngRoute']);
app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
$routeProvider.
when('/services', {
templateUrl: './partials/services.html'
}).
when('/contact', {
templateUrl: './partials/contact.html'
}).
when('/home', {
templateUrl: './partials/home.html'
}).
otherwise({
redirectTo: '/home'
});
}]);
app.controller('MainCtrl', function ($scope) {
});
I get this error:
XMLHttpRequest cannot load file:///partials/home.html. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
Now I'm guessing this is because I don't have a webserver running. How do I get it to work without a webserver?
solution
When I uploaded the files to github it seems to work there, but not locally.
Looks like you are using ngRoute and forgot to include it!
First load angular-route.js after loading angular.js. The inject ngRoute as a module:
var app = angular.module('cerrajero', ['ngRoute']);
Try removing the array syntax brackets from inside your config function. I believe there are two different ways of invoking these functions, either with a standalone function or with an array for any minification processes.
You should either one of the following:
app.config(function ($locationProvider, $routeProvider) {
// your code here
});
Or define the variable names with the array syntax for use in minifiers
app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
// your code here
}]);
When you pass in an array to the config function, I believe Angular is expecting the first parameters to be a string value.
You should use ui-router instead of ng-route. It will allow you to nest views. Most current Angular projects use ui-router. ui-router scotch.io
Also, for your controller try app.controller('MainCtrl', function($scope){...});
Replace
var app = angular.module('cerrajero', []);
with
var app = angular.module('cerrajero', ['ngRoute']);
I've been creating a contact list website and have just begun trying to implement an add contact function. So far I have created the page using a form and input elements and then use ng-click to call a function which theoretically would add an object containing these input values into an already-existing array in the controller. For some reason this doesn't work and nothing is added.
In particular, I'm having trouble with the js/app.js file and the $scope.saveContact = function() in relation to the partial/edit.html webpage. Clicking the "Confirm button" when trying to add a contact calls the saveContact function, but the results are not stored properly. Any help is appreciated.
In my HTML I have this code (which calls the saveContact() function in my controller.
<a href="#/"><div class="confirm col-xs-6" ng-click="saveContact()">
<h3>Confirm</h3>
</div></a>
In my app.js file I have a declaration of an empty object and an array containing objects that already have values (used to display the contacts that are already created). I'm trying to add to these contacts using .push() but it for some reason it doesn't work.
$scope.contact = { ... } //empty object that gets inputs from HTML
$scope.contacts = [ { ... }, ... ];
$scope.saveContact = function(){
$scope.contacts.push($scope.contact);
};
This bottom function fails to push the contact object to the contacts array and I don't understand why.
This is happening as you have assigned same controller to all your routes. Your saveContact function is working fine, its pushing the object to the array. As soon as the route changes, a new instance of the controller is created and hence the added object is lost. You should create a service(singleton) to store the object and inject the service as a dependency to the controller. In this way the array will persist until the page load.
app.service("storeContact", function(){
var contacts = [];
this.setContact = function(cnt){
contacts.push(cnt)
};
this.getContact = function(){
return contacts;
}
});
And inject it in the controller and use the setContact and getContact methods to update the contact array and retrieve the contact array.
Ideally, you should have separate controllers for your route.
The issue is in your app.config code. You are using the same controller for all your templates.
This is not required since you have already mentioned the same in ng-controller attached with body
<body ng-controller="AppController">
<div ng-view></div>
<script src="js/app.js"></script>
</body>
Using same controller for all your routes is essentially (re)instantiating the controllers when the route is changed and thats the reason why $scope.contacts.push($scope.contact); is ineffective for the route / when called from /add.
contactListApp.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
controller: 'AppController',
controllerAs: 'list',
templateUrl: 'partials/list.html'
})
.when('/add', {
controller: 'AppController',
controllerAs: 'add',
templateUrl: 'partials/edit.html'
})
.when('/edit/:id', {
controller: 'AppController',
controllerAs: 'edit',
templateUrl: 'partials/edit.html'
})
.otherwise({
redirectTo: '/'
});
}]);
Workaround:
Either use separate controllers for separate routes and use a service to store the object
OR
Simply remove the controller and controller as from your route config and you are good to go.
Updated config:
contactListApp.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/list.html'
})
.when('/add', {
templateUrl: 'partials/edit.html'
})
.when('/edit/:id', {
templateUrl: 'partials/edit.html'
})
.otherwise({
redirectTo: '/'
});
}]);