So I'm running into a problem with Angular 1.3.15 and the $locationProvider. Every time I turn html5mode on I get a TypeError: Cannot read property 'replace' of undefined error. If I leave html5mode off, everything works fine.
My directory structure is like so (4.DEV being a versioned directory name):
public /
- index.html
4.DEV /
css /
js /
images /
partials /
etc...
I have a base tag set like this:
<base href="/4.DEV/">
And I'm configuring the $locationProvider like so:
$locationProvider.html5Mode({ enabled: true });
If I change the base tag href to "/" Angular doesn't have any issues (but my assets don't load). I suspect that the issue Angular is having deals with the fact that my index.html file is one directory up from the rest of the site.
For reasons I won't list here, I can't change this dir structure and I REALLY don't want to change the base tag (because I don't want to manually stick a version number into all these files). I also want to leave html5mode on.
Does anyone have a solution for this problem? Is there any way for me to MANUALLY set the "base href" for Angular, but leave the tag alone for all my static assets?
So, it looks like Angular's inner workings are tightly coupled to the href of the tag which results in major issues if you have a directory structure that's a bit unconventional like mine.
Stumbled across this Github thread where people are asking for a feature to change this and #greglockwood posted a fix.
With his fix, the tag can work for your static assets while you provide your own set "baseHref" for Angular's stuff.
Worked like a charm for me! Hope this helps anyone who stumbles across this!
Related
I have a group of images at my root level and I also have a page called Help. If I navigate to rootspace/Help angular knows to get the images from the root repository, but if I change it to rootspace/Help/ then angular thinks the files are in a folder 'Help' that doesn't exist. I need the extra slash because I want to put more information after it.
How can I maintain '/Help/' without angular thinking this is part of the path it needs to find resources?
How are you getting the images? I'd recommend creating a resouce, this way angular will always know where to find the images if you provide a base url. It will also be easy to configure later on if you change the location of the images.
Example code:
angular.module('resources', ['$resource'])
.factory('Images', function($resource) {
return $resource(baseUrlGoesHere + '/images', {}, {})
})
Then you can inject the resource into your controller and call Images.get()
BTW, you probably can't use the code as is, I think the injection of $resource will fail but I'm not sure.
All,
I am developing an Angular app (not my first) within an existing JavaScript application that is primarily based in jQuery and Django templates.
In order to get to my Angular application from within the existing application, the URL will look like this:
/existing-application/#myapp/myapp
I realized early that I would have to avoid the injection of $location anywhere in my application or else have Angular become utterly confused with the existing # (hashtag) in the URL.
I have reached a point where this is no longer an option. Therefore, I am setting html5Mode: true and am working with the <base href="" /> header tag to try and find a solution.
However, the closest I have come to having this approach working results in a URL that looks like this after my page renders:
/existing-application/#myapp%2Fmyapp
I currently have a base tag of:
<base href="/existing-application/#myapp/myapp" />
This will load the Angular app. successfully but the URL is then rewritten automatically to:
/existing-application/#myapp%2Fmyapp
Which causes all sorts of problems within and outside of my Angular application.
I have read some reports of bugs wherein there is an issue with $location.rewrite that causes the trailing '/' to become escaped.
I have attempted to work around this issue in several ways, from modifying the <base /> tag, calling $location.path('/existing-application/#myapp/myapp) on page load, using $routeProvider, changing the hashPrefix, and it seems the closest I can ever come to is the escaped trailing slash.
Changing the hashPrefix to '!' merely resulted in:
/existing-application/#!#myapp/myapp
Any advice on what to try next? I am not opposed to not using html5Mode, but without doing so I don't believe this approach will ever work.
Thank you.
Config Block:
.config(['$locationProvider', '$interpolateProvider', '$websocketProvider',
function($locationProvider, $interpolateProvider, $websocketProvider) {
// inject meta 'base' href into <head> tag
$('head').append('<base href="/existing-application/#myapp/myapp" />');
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: true
});
Angular Information:
Angular v. 1.3.1
We have a product that is a widget people load onto their site, which consists of a single JS file that also needs angular to run, so angular is bundled into the JS file.
However, if a site already is using and loading angular themselves, when they load our widget they get an error which kills everything with the following:
WARNING: Tried to load angular more than once
Which makes complete sense since angular was indeed loaded more than once.
What we'd like to do is either of the following:
In our script, rename / namespace angular so it does't conflict with
the host sites already loaded angular, or
Detect if angular is
already loaded, and if so don't load angular ourselves.
To show examples of our code would be difficult since it's spread over about 20 files etc, however it's based off the following angular seed project which uses requirejs to load everything, then we're compiling to a single file: https://github.com/tnajdek/angular-requirejs-seed
Would really appreciate any feedback / tips / solutions
NB This is not a duplicate of any "check if angular loaded correctly" type questions, angular is packaged inside our widget js, the issue comes when angular is also already loaded by the parent page. We need a way to rename angular inside our package.
I'd advise taking a look at this answer, it has to do with a chrome extension running in the same circumstance. The idea here is to separate your loading of angular from the website's, and it assumes that your widget will be loaded after the main content of the page has been loaded.
If you are loading in html content with an ng-app directive or ng-controller, wrap your html content in a container with ng-non-bindable as an attribute.
Angular looks immediately for an element with the ng-app attribute when you load in angular.js. If two ng-apps are present i.e., on your site, and the widget, it will cause errors. Defer the parsing with: window.name = "NG_DEFER_BOOTSTRAP!" + window.name; Then load in your script.
Once your script has loaded, set window.name to '' or whatever it was before.
Individually bootstrap (the term for angular finding an ng-app attribute) your html content using:
var appRoot = document.querySelector('#id');
angular.bootstrap(appRoot, ['angularModuleName']);
And that should do it... Caveat, I have no idea how this would work if your widget Angular is on a different version than the client website, and I've only made it work with extensions, which are a little bit different because they live in their own isolated 'worlds'.
That being said, I feel like this should get people going in the right direction when dealing with this problem.
I'm building an Adobe AIR application with AngularJS. And have quickly come across a problem in that Angular can't see partials below a certain level and any $http resources.
I've read here: How to Adjust Angular's URL matching pattern that this is because of the way Angular looks at URLs instead of using app:/ but in 2.0+ it no longer has a SERVER_MATCH so I can't use that regex... if that's even the issue anymore?
Basically if I have a index.html like:
<div ng-include="'partials/header.html'"></div>
<div ng-view></div>
<div ng-include="'partials/footer.html'"></div>
It will find those two includes fine! But if in header I have:
<div class="header">
<div ng-include="'partials/header-nav.html'"></div>
</div>
Angular won't see that header-nav in Adobe AIR, because it seems to lose where partials folder is in relation to the rest of the application... I'd assume that all resources also break for this same reason!
This also doesn't work:
phonecatServices.factory('Phone', ['$resource',
function($resource){
return $resource('phones/:phoneId.json', {}, {
query: {method:'GET', params:{phoneId:'phones'}, isArray:true}
});
}]);
Even if I was to call this on the index route, it won't find the JSON file as the factory doesn't know where to find the file...
Setting <base href="app:/"> doesn't fix it either but also breaks the links so that's not a solution...
Any ideas? I'm assuming it's something simple...
This sounds more like server issue then angular.
Are you using paths with hashes? If no, try to, maybe bowser is confused by changing the address bar path and relative urls.
Are you using grunt to build the project? It's worth a try, and then you can use grunt-angular-templates to build them into one js file. There really isn't any reason to make multiple requests for html form you production env.
Load your index.html from the web server.
Then all your resources will be loaded relative to that including the angularJS which will load things like templates.
You can use StageWebView as shown below:-
var webView:StageWebView = new StageWebView();
public function StageWebViewExample() {
webView.stage = this.stage;
webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
webView.loadURL( "http://localhost:9000/app/index.html" );
}
Other options are included in my comments to OP's questions but this should serve the solution well in the constraints of the problem defined by OP.
I've just started using angular and javascript and I can't really figure out how to structure my application.
I started writing a Controller and my first reflex is to put what I would call my model into a class in a different file.
I have different option
1 - putting everything (model + controller ) in one file
2 - using requireJS so my controller can 'include' my model. I've managed to do it, put it wasn't straight forward and I still have problem to make the yeoman dist version to work.
3 - use angular module, which seems to be the recommended way, but if choose this solution do I need to load explicitly my model file in the main html file. I understand that not hardcoding the dependency between files can be a good thing, so you can for example swap or change some components, but it seems wrong when for example a subclass need to requires its parent class. If I need to split a module in lots of angular submodules, do I need to load them all explicitly ? That's seem totally wrong.
Am I missing something ? what is the standard way to do so ?
What I found quite useful are the MTV meetup sessions. They give a good overview about how to apply best practices in AngularJS:
Best Practices: http://www.youtube.com/watch?v=ZhfUv0spHCY
Angular+Yeoman: http://www.youtube.com/watch?v=XOmwZopzcTA
There are many more videos on youtube. I hope this helps giving a first idea.