OK, just when I think I understand AngularJS I get zapped.
I have an application that uses a number of different google maps. I want the user to click on a marker and then have the system so to a new screen with information relating to what was clicked.
Everything is working well up to a point. I get the click event and then get ready to go to the appropriate screen. My code at that point looks like:
$window.location.href = "#/" + ScreenName + "/" + Parameter ;
At this point I get the error:
ReferenceError: Can't find variable: $window
Which searching tells me I need to inject $window
I have tried a bunch of different ways to do this injection, but this is also where my personnal knowledge base fails me.
I think I need to have my app.js file look like this:
.config([
'$routeProvider',
function($routeProvider)
{
$routeProvider.
when("/customer/:cust_gid", {templateUrl: "views/div_Cust.html", controller: "customerController"}).
when("/location/:locn_gid", {templateUrl: "views/div_Locn.html",controller: "locationController"}).
otherwise({redirectTo: '/utilities'});
}])
.config(function ($windowProvider) {
var $window = $windowProvider.$get();
console.log($window);
});
This does nothing for me. I need to know If I am close and just don't have the syntax right or is there something else missing.
Do I need an include file in my index.html file to load $windows?
Can someone give me a kindergarten level answer to this question.
Appreciate
Stan
$windows is a globally service which is included in angularjs.
You don't need an extra library reference for it.
To use it, just inject is as any other service in the controller which should use it
app.controller('locationController', function($scope, $window)..
Related
I'm using $routeProvider to create a one page app where users press continue to go to the next step. It is important to pass variables to the next page whenever a user clicks continue so I followed some advice and created my own service which has persistent variables. This all works great except that I can only get variables from the service, I don't know how to update the variables. Here is my code:
myApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/pick_categories', {
templateUrl: '/pick_categories.html',
controller: 'MeetupDataCtrl'
}).
when('/pick_times', {
templateUrl: '/pick_times.html',
controller: 'MeetupDataCtrl'
}).
when('/events', {
templateUrl: '/events.html',
controller: 'MeetupDataCtrl'
}).
otherwise({
redirectTo: '/pick_categories'
});
}]);
myApp.service("meetupService", function(){
this.checked_categories = [];
});
myApp.controller('MeetupDataCtrl', ['$scope', '$http', '$location', '$resource', 'meetupService', function MeetupDataCtrl($scope, $http, $location, $resource, meetupService) {
$scope.checked_categories = meetupService.checked_categories;
}]);
Then in the view I have checked_categories bound to an input field.
I know the problem is that I'm getting the service's variables on init, but I'm not updating the service's variables from the scope after I change routes. Any ideas on how I could do this? (or if there are other best practices)
You could in fact change the service properties directly ... :
meetupService.checked_categories.push({ something: 'something'});
... but it's better to encapsulate the state properties of a service so you can do something like the following from your controller:
meetupService.addCategory('theCheckedCategory');
Do mind that services are singletons in Angular; there will be only one meetupService in your Angular application. This means that once the user has modified the checked_categories array somehow they will have that some array until they refresh/reload your website.
Also note that passing state information via url arguments is in most cases not necessary when building a single page app (which Angular is).
It sounds like your trying to build a wizard and if I'm guessing right you don't need anything of the above. Wizards are actually quite easy to make in Angular because all the state information is kept, ... well as long as you want it to.
See this plunker for a simple wizard example.
Edit:
Oh, and if you really need to pass arguments to the route, you can do that with the builtin $location service.
// change the path
$location.path('/newValue')
// change the query string / url arguments
$location.search({myArg: 'value', myOtherArg: 'anotherValue'});
I have a simple angularjs application with a single router at the moment :
angular.module('myApp', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/editFilter/:id', {templateUrl: '/webapp/template/filterDetail'});
}])
My goal is to call the editFilter template when I need it.
I am trying to retrieve the $location like that :
angular.injector(['myApp']).get('$location')
but it fails with
Error: [$injector:unpr]
http://errors.angularjs.org/1.2.1/$injector/unpr?p0=%24rootElementProvider%20%3C-%20%24rootElement%20%3C-%20%24location%20%3C-%20%24route
If I call angular.injector(['myApp']).get('$location') it returns true.
Any idea of what I am doing wrong? I have try several workaround but everytime I end up with a very similar error.
If you would have read the error page you see that you forgot to include certain dependencies. Please don't forget to include them. The one failing now is $rootElement, as you can read in the error. Include this one, and try again to see if other dependencies should be included.
EDIT:
OK, I was wrong, after some reading I noticed that this method:
angular.injector(['myApp']).get('$location')
creates a new injector instance. This is not what you want I think.
So I don't know what is your case but if you are in AngularJS just inject the $injector instance. If not in AngularJS call
$injector = angular.element([DOM element]).injector();
$injector.get('$location');
I'm new to angularjs and want to integrate it in a cakephp app. For some pages I don't have a controller since no javascript is exectuted there or because I still have to create them. I however don't want to list them all in the routes. For this reason i set it like the following:
angular.module('desktop', []).
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {templateUrl: 'pages/index', controller: IndexController})
.when('/clubs', {templateUrl: 'partials/clubs.html',controller: ClubListController})
.otherwise({templateUrl: location.pathname});
}]);
This is however not working. When I go to /help, nothing happens. What am i doing wrong?
From my comments:
As far as I know it there is currently no way to do this with just routes. Routes are made to be static, they are defined as the app loads and do not update dynamically as time goes by. So using location.pathname() (or directly checking window.location) won't work since the route be set to whatever the value is when the app starts, and then never change again. It won't update when you load a new path unless you do a full browser reload (this is btw possible, but a hacky sollution).
But people have been working around it using includes, which might work for you depending on what you are after. See this question and the accepted answer for an example of how this works.
AngularJS - How to use $routeParams in generating the templateUrl?
I'm coming from a PHP MVC background and I'm starting to use AngularJS. In PHP I would do something like this to direct the user to different parts of a website: grab the url, split it up, then send the user to the requested page. For example, if the user entered www.mysite.com/info/product/1, then PHP would split up this url and say "okay, use the 'info' controller." Then, the 'info' controller would say "okay, use the product controller." This controller would do what it does, and then send the user to the requested url.
In angular I'm trying to figure out the equivalent to this. I've seen things like this:
angular.module('phonecat', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}).
when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
otherwise({redirectTo: '/phones'});
}]);
Does this mean that I have to enter in every possible url this way? In other words, do I have to duplicate the above code for any url that is a sub link of www.mysite.com/phones/. Like this:
....
when('/phones',...).
when('/phones/:phoneId',...).
...
and then do the same for some other directory (e.g., www.mysite.com/computers/...).
Any help would be greatly appreciated.
It looks like you're on the right path (pun intended).
In the route provider you define what view and controller will be used for a given URL ($location) essentially. Along with the path itself you can include parameters as you show with phoneId. Keep in mind these aren't paths on the server, these are simply URLs being used by the angular application to keep track of it's history and navigate for "deep linking" to show the appropriate view when a link is copied.
If you're doing some sort of RESTful interface where the PHP has some "directory structure" or URL that implies the data model that is a separate issue. You would handle that by using the $resource in AngularJS I believe though I'm not familiar with actually implementing this. So far I've used $http in a service I define to handle my calls to the server and am just manually setting up what files are called, but for large complex projects a REST interface is probably a good idea so as to avoid all the manual work and potential errors.
I have an AngularJS application into which I want to load some plugins that are discovered by a controller when it starts up. In order for the plug in to work I have add some routes to the $routeProvider from the controller, but there seems to be no way to do this.
Right now I'm using a pretty ugly hack as below:
var routeProvider;
angular.module('example', [], function($routeProvider) {
routeProvider = $routeProvider;
// Set up other routes
}
function Controller($http, $location, $timeout) {
// Use $http to find some plugin
routeProvider.when(plugin.url, plugin.options);
// Ugly hack so that the plugin appears if $location.path() already points to it
var path = $location.path();
$location.path("/");
$timeout(function() { $location.path(path); }, 10);
}
If I don't do the nonsense with $timeout then if I start (load the page) at the route for the plugin it won't load ($route.current remains blank). With the jump between paths the route gets resolved properly and the plugin view loads as it should.
Is there a better way of doing this?
You could tear $routeProvider from the source and make your own version? :-)
$routeProvider is just a provider made for you. https://github.com/angular/angular.js/blob/master/src/ng/route.js
The way that we did this in the end was to have all of the routes downloaded from services before we start up AngularJS and then use that data structure to set up the routes, then bootstrap Angular once we had the information and everything was set up properly.
The only downside of this is the delay in start up, especially if there are multiple service plug ins that you need to handle.