Working through this tutorial on AngularJS with MeteorJS, but have run into some issues with ui.router, $stateProvider, and $locationProvider.
My issues is that, as far as I can tell, everything should be wired up properly for routing, but my links don't actually work. Contents of my main files are below, but first more information about the problem:
The problem seems to be with the line //$locationProvider.html5mode(true); in app.js. Its currently commented out, which allows the page to load, but doesn't route the links properly. If I uncomment it, then the page returns the following error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module socially due to:
TypeError: undefined is not a function
I assume in reference to $locationProvider being undefined. This looks a lot like a dependency injection error, but I can't find any dependency injection errors. Any help much appreciated.
app.js
if (Meteor.isClient){
angular.module("socially", ['angular-meteor', 'ui.router']);
angular.module("socially").config(['$urlRouterProvider', '$stateProvider', '$locationProvider', function($urlRouterProvider, $stateProvider, $locationProvider) {
$stateProvider
.state('parties', {
url: '/parties',
templateUrl: 'parties-list.ng.html',
controller: 'PartiesListCtrl'
})
.state('partyDetails', {
url: '/parties/:partyId',
templateUrl: 'party-details.ng.html',
controller: 'PartyDetailsCtrl'
});
$urlRouterProvider.otherwise('/parties');
//$locationProvider.html5mode(true);
}]);
angular.module("socially").controller("PartiesListCtrl", ['$scope', '$meteor', function($scope, $meteor){
$scope.parties = $meteor.collection(Parties);
$scope.remove = function(party){
$scope.parties.remove(party);
};
$scope.removeAll = function(){
$scope.parties.remove();
};
}]);
angular.module("socially").controller('PartyDetailsCtrl', ['$scope', '$stateParams', function($scope, $stateParams){
$scope.partyId = $stateParams.partyId;
}]);
}
index.html
<head>
<base href="/">
</head>
<body>
<div ng-app="socially">
<h1>
Home
</h1>
<div ui-view></div>
</div>
</body>
parties-list.ng.html
<form>
<label>Name</label>
<input ng-model="newParty.name">
<label>Description</label>
<input ng-model="newParty.desc">
<button ng-click="parties.push(newParty)">Add</button>
</form>
<ul>
<li ng-repeat="party in parties">
{{party.name}}
<p>{{party.desc}}</p>
<p>{{party.name}}</p>
<button ng-click="remove(party)">X</button>
</li>
</ul>
party-details.ng.html
Here you will see the details of party number: {{ partyId }}
I just started using meteor-angular recently as well.
After testing - it looks like your issue was a simple lowercased 'm'.
I can see how the '5' could make camel case confusing.
Corrected: $locationProvider.html5Mode(true);
Related
I want to use Angular-route to change the controller used in a page
This is some part of my angular code
var cat_list = angular.module('getCat', ['ngRoute']);
cat_list.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('category/upcoming', {
controller: 'getUpcoming'
})
.when('category/popular', {
controller: 'getPopular'
});
$locationProvider.html5Mode(true);
});
cat_list.controller('getUpcoming', ['$scope', function($scope, $routeParams) {
//controller code goes here
});
cat_list.controller('getPopular', ['$scope', function($scope, $routeParams) {
//controller code goes here
});
and this is some part of my html
<div class="row" ng-app="getCat">
<div class="col-md-12">
<!-- something happen in here -->
</div>
</div>
but when I tried to visit http://localhost/project/category/upcoming or http://localhost/project/category/popularthe route is not working (no controller picked or selected)
did I miss something?
Try this
var cat_list = angular.module('getCat', ['ngRoute']);
cat_list.config(['$routeProvider', '$locationProvider',
etc etc.
Could you also please explain why you want to use different controllers on the same page? Why dont you use two different partials to create two seperate pages for upcoming and popular?
Or, a different approach would be to just use the same controller, and filter your results using the appropriate directive, without changing the stuff that you load each time.
Have to mention ng-view, so that this directive is the placeholder to replace your view partials on url changes.
<div class="row" ng-app="getCat">
<div class="col-md-12">
<div ng-view></div> // ---- This is the thing you missed
</div>
</div>
I'm building a toy app in Angular/Rails and I have most of the angular ui routing working, but it doesnt seem to display the template. I know the controller is being loaded because I put a debugger and it freezes in the chrome dev tools.
Link to github branch
EDIT: Its probably because the templateUrl specified isnt a valid route. It's injected the root html file into itself and requiring angular multiple times. Absolute paths don't work either. Still no solution.
Here's some of my code:
I also know the redirect routing works because I've tested it in local host.
angular.module('SwoleMetrics', [
'ui.router',
'templates'
])
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
/**
* Routes and States
*/
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
controller: 'DashboardCtrl'
});
// default fall back route
$urlRouterProvider.otherwise('/dashboard');
// enable HTML5 Mode for SEO
$locationProvider.html5Mode(true);
});
Here's the controller:
angular.module('SwoleMetrics')
.controller('DashboardCtrl', function ($scope) {
$scope.things = ['Angular', 'Rails 4.1', 'UI Router', 'Together!!'];
});
And finally the template:
<div class="container">
<h1>The Home View!</h1>
<ul>
<li ng-repeat="thing in things">{{thing}}</li>
</ul>
</div>
It goes inside this tag but I dont think this is the issue:
<div class="main-view-container" ui-view></div>
I'm using angular-ui-templates 1.4.0 if that helps.
I have a JavaScript web app where I used AngularJS to ease things up, but now I bumped into a little problem.
I want to change viewfrom an ng-controller. I use $location.path to do this, but sadly, nothing happens. If I check the $location object, the path will be changed correctly, but the view isn't changing.
I have an ng-view in my Home.html. This is the config I wrote for it:
<html ng-app="app">
...
<body>
<div id="navigation-menu" ng-controller="NavigatorController">
<a class="menulink" ng-class="{ active: isActive('/labels')}" href="#page2">Page2</a>
<a class="menulink" ng-class="{ active: isActive('/labels')}" href="#page3">Page3</a>
</div>
<div ng-view></div>
</body>
</html>
This is the config I made for the $routeProvider which works flawlessly when used in the menusystem
myApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'Page1.html',
controller: 'Page1Controller'
})
.when('/page2', {
templateUrl: 'Page2.html',
controller: 'Page2Controller'
})
.when('/page3', {
templateUrl: 'Page3.html',
controller: 'Page3Controller'
});
});
Upon opening the app I want to show the Page1.html in the ng-view, so that's sorted with the '/' url thing, I guess.
The problem is, that from every other controller, I want to be able to get back to the Page1.html.
I tried making an event in every other controller, like this:
$scope.NavigateBack = function() {
$location.path('/');
}
It's not working, sadly. I don't get any error messages though... I tried it with different addresses in the path, like "/page2", but nothing worked.
What am I doing wrong, that the view isn't changing and the page isn't navigating?
I recommend use
$window.location = "#/"
but don't forgot to inject $window to your controller
Define behaviour in the Page2Controller, for example:
$scope.goBack = function(){
$location.path("#/");
}
And add some button inside of Page2.html:
<button ng-click="goBack()">Return</button>
You might also need to change your navigation links href attribute to #/page2 and #/page3
everyone. Has anyone else encountered jQuery console errors when routing to new views with AngularJS?
An example of the error is
Uncaught Error: Syntax error, unrecognized expression: #/projects/project-id
Everything still works, but that error gets thrown whenever a link is clicked that is related to my Angular routing. The error shows up attributed to jQuery, so I assume it's an issue with it not liking links starting with "#/"
HTML
<div class="project" ng-repeat="project in projects">
<a href="#/projects/{{project.id}}">
<h4>{{ project.name }}</h4>
<p>{{ project.subtitle }}</p>
</a>
</div>
JS
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: "HomeController",
templateUrl: "js/angular/views/home-view.html"
})
.when('/projects/:projectId', {
controller: 'ProjectController',
templateUrl: 'js/angular/views/project-view.html',
})
.otherwise({
redirectTo: '/'
});
});
The console error isn't a showstoppper, because like I said, everything still works. But if anyone has encountered this before and has a fix, I'd really appreciate it.
Set the $locationProvider to work in HTML5 mode. See here: https://docs.angularjs.org/api/ng/provider/$locationProvider
An example of how to use it would be the following:
app.config(function ($locationProvider) {
// use the HTML5 History API
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
I have a url that's getting passed into my Angular code via Rails. However, when I try to pick up a parameter in the url, it shows up as blank. Can anyone help me out?
Sample url: http://localhost:3000/events/event1
Plnkr: http://plnkr.co/edit/yG8wAZHhgPtH2PBFzql3?p=preview
Angular:
eventsApp = angular.module('EventsApp', ['ngRoute'])
eventsApp.config [
'$routeProvider'
'$locationProvider'
($routeProvider, $locationProvider) ->
$locationProvider.html5Mode(true)
$routeProvider.when '/events/:eventName',
templateUrl: '../../views/events/events.html.erb'
controller: 'EventsCtrl'
return
]
eventsApp.controller('EventsCtrl', [
'$scope'
'$routeParams'
($scope, $routeParams) ->
console.log($routeParams.eventName) # shows up as undefined
$scope.greeting = $routeParams.eventName
])
HTML:
events.html.erb
<div>
{{greeting}}
</div>
application.html.erb (overall layout)
<div id="content" ng-app="EventsApp">
<div ng-view></div>
<%= yield %>
</div>
Edit: As suggested, I've moved ng-app and ng-view into the layout and kept only the div inside events.html.erb
If the bugs pointed by Karaxuna still giving you empty result, it might be because of the asynchronous operation of $routeParams
$routeParams usually takes some time to load. It is being loaded asynchronously. When you are trying to use it, it might not ready and still empty. One approach is, create event listener when the route is ready.
$scope.$on('$routeChangeSuccess', function() {
console.log($routeParams.eventName);
});
It's because you have included controller with ng-controller directive instead of ng-view. It must be like this:
<body ng-app="EventsApp">
<div ng-view></div>
</body>
In events.html.erb:
<div>
{{greeting}}
</div>