Angular Routing templateUrl with Express backend not working - javascript

I am having an issue getting a partial to display using angular routing and express. I am trying to set things up so I can still use pug (formerly jade) to write shortform html. As far as I can tell, everything should be working, no errors, everything is pulling correctly. I have most other portions of the application working (api calls, controllers, etc.) My main page is as follows:
doctype html
html(ng-app='myapp')
head
base(href='/')
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js")
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-route.js")
body
header#main
.content(ng-view)
script(src="/js/app.js")
script(src="/js/controllers/adminController.js")
script(src="/js/routes.js")
Here is my routes file
angular.module('myapp')
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/admin', {
templateUrl: '/templates/admin',
controller: 'AdminController',
caseInsensitiveMatch: true
})
.otherwise({
template: '<h1>Page not found</h1>'
})
;
$locationProvider.html5Mode(true);
});
And finally, the express route:
router.get('/templates/:name', function(req, res, next) {
var name = 'templates/' + req.params.name;
console.log('Express: ' + name);
res.render(name, function(err, html){
//this callback function can be removed. It's just for debugging.
if(err)
console.log("Error: " + err);
else
console.log("We're good!");
res.send(html);
});
});
Lastly, here is the node server output:
Express: index
GET /admin 304 68.962 ms - -
GET /js/app.js 304 0.994 ms - -
GET /js/controllers/adminController.js 304 0.751 ms - -
GET /js/routes.js 304 14.590 ms - -
Express: templates/admin
We're good!
GET /templates/admin 304 368.081 ms - -
As you can see, the index loads, calls the partial, and the template is getting called and rendered just as you would expect.
The problem is ng-view is not getting replaced or updated. It all works just fine if I change the route to template instead of templateUrl, and just print out a line of text, so I know routing is working and this isn't an app configuration issue.
I've been stuck on this for a few days, and without any error messages, I am completely in the the dark as to why this doesn't work.
Additionally, when I check the following in my controller, I get the partial, so it is coming through properly:
angular.module('buriedcinema.controllers')
.controller('AdminController', ['$templateCache', function(Movies, Users, $templateCache){
console.log($templateCache.get('templates/admin'));
}
console:
<h1> this is my partial </h1>

Fixed by adding "controllerAs:" option to my routing and referring to my controller by the object name.
.when('/admin', {
templateUrl: 'templates/admin',
controller: 'AdminController',
controllerAs: 'adminCtrl',
caseInsensitiveMatch: true
})
The more technical explanation is that I wasn't instantiating an object with state, but trying to use my controller statically so it never updated. Hope this can help someone else.

Related

angular.js Routing doesn't work on the server

I'm using ngRoute in my site, it work well on my computer (local) but on the server routing doesn't work. On my computer all my files are html, on the server i rename them as php. How can i fix it?
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider, $compileProvider) {
$routeProvider
.when("/", {
templateUrl : "pages/main.php",
controller: 'oneCtrl'
})
.when("/about", {
templateUrl : "pages/about.php"
})
.when("/news", {
templateUrl : "pages/news.php"
})
});
Based on the error messages you're getting (as you said in the comments), the Angular library is not being loaded. Double-check the URL. Also in the browser dev tools, check the Network tab and see what error it shows. Probably a 404 not found.
After checking your website and the line where you said the error was occurring (line 156 of route.js), change your code to this:
$('.counter-one span').eq(0).html(value1 + ' ');
$('.counter-two span').eq(0).html(value2 + ' ');
You did a search/replace for "html" to "php" but that also replaced the jQuery html() command. Just fix these two lines and you should be good.

Angularjs routing doesnt work when reloading the page manually

I am trying to reload the page mannually from the browser but it doesn't work and says
Cannot GET /rate/4
My route:
angular.module('routing')
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/views/index.html'
})
.when('/rate/:cid', {
templateUrl: 'app/views/rate.html'
})
.otherwise({
'redirectTo': '/'
});
$locationProvider.html5Mode(true);
});
My assumption is that when I am reloading the main (index.html) is not loaded which is my base html file.
You do not have an angular problem, you have a server problem.
You're essentially working with a single page application.
When the server receives a request for rate/4 it must return index.html (or whatever the name that your main page is).
How you solve this will depend upon what platform you've implemented your server in.
For example, if you were running a node express server, you would have this kind of routing code:
app.get(/^\/rate\/.*/, function(req, res) {
// This matches a known pattern for a client-side route
res.sendFile(__dirname + '\\public\index.html');
});

express + angularjs : app hangs on invalid url

I am facing a weird issue with angular and express,
I have a very simple routing on app.js as below :
app.get('/partials/:name', routes.partials);
app.get('*', routes.index);
also this is on my angular routerprovider :
$routeProvider.
when('/', {
templateUrl: '/partials/home'
}).
when('/contact', {
templateUrl: '/partials/contact'
}).
otherwise({
templateUrl: '/partials/error'
});
now the problem is, if I enter below invalid url, it goes to error page [OK]
http://www.devnest.io/someInvalidpath // it will go to /partials/error
But if I enter an invalid url with two level path (or more) page will hang [NOT OK]
http://www.devnest.io/someInvalidpath/AnotherInvalidPath // page will hang without error
and in the developer tools, it likes infinite loop and page call, like this picture :
also there is no error on node.js or angular ...
I am really confused, can anyone help me, on which part my routing is not correct ?
Thanks,
Try
app.use(routes.index);
instead of
app.get('*', routes.index);

AngularJS routing Server side support (NodeJS+express)

I am using NodeJS + expressJS on server and AngularJS on client
AngularJS controller have the following routes:
app.config(function($routeProvider,$locationProvider) {
$routeProvider
.when('/field1/:id', {
controller: 'ctrl1',
templateUrl: "/view/mainpages/field1.html"
})
.when('/field2/:id', {
controller: 'ctrl2',
templateUrl: "/view/mainpages/field2.html"
})
........... many many
.when('/', {
controller: 'ctrl0',
templateUrl: "/view/mainpages/index.html"
})
.otherwise({redirectTo : '/'});
NodeJS static:
app.all('/*', express.static(__dirname + '/client'));
How to make the server redirects all the static pages on their paths relative to the root, in the case when the call goes directly through this link.
example:
server:3000/field1/23 must call server:3000/client/index.html
and index must upload JS like server:3000/js/cntr1.js
Upd: I found a solution to the problem. But it looks ugly as a crutch
app.get('/field1/([0-9]+$)', function(req, res, next) {
req.url='/index.html';
next();
});
app.use('/field1', express.static(__dirname + '/client'));
Perhaps there is a more elegant solution?
In expressjs, you can define the route using regular expression pattern matching. That means, anything under a specific set will always return the same page from the server side, and you will let angular decide what exactly to display or do which action.
Its not a great idea to redirect everything at / to same page as you need to manage your assets and they exist on the / part too , instead its a good idea to use a subdir which is easy to manage
Following snippet will redirect everything under the app path to the same page on server side
app.get('/app/*', function(req, res) {
res.send('app_index');
})
if you do not want to be limited to one app dir, instead you have a number of different root level dirs, all of which need to point to the same page, you can do something like this
app.get('/(app|server|client|form|dashboard)/*', function(req, res) {
res.send('app_index');
})

Navigating to non-default state with ui router

I have been trying to figure this out off and on for a few days now and everything I have read on the internet says that it should just work. My app routing works just fine as long as I am in the app, but when I try to copy and paste a url it loses its state and redirects to home.
* edit
I am starting to think it is because app.yaml is handling the "serve up index.html no matter what", it seems like whatever app.yaml does it strips information away and thats why $state has a url of ""
edit *
I have my server configured to return index.html no matter what the url so it is getting to the routing logic with the url I pasted still in the browser bar. When I put a breakpoint in the run block where I inject $state and $stateParams it shows the current url is "", when it gets to the config block with my routes it goes to the .otherwise('/') and redirects me to the start of the app.
app.run([
'$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams){
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
console.log($rootScope);
}])
.config([
'$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider){
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/layout/home.html',
controller: function($stateParams){
debugger;
}
})
.state('other', {
url: '/{abc:[a|b|c|d]}',
templateUrl: 'app/layout/other.html'
});
}]);
Here is my app.yaml
application: app
version: 1
runtime: python27
api_version: 1
threadsafe: no
handlers:
- url: /(.*\.(gif|png|jpg|ico|js|css|html))
static_files: \1
upload: (.*\.(gif|png|jpg|ico|js|css|html))
- url: /robots.txt
static_files: robots.txt
upload: robots.txt
- url: .*
static_files: index.html
upload: index.html //I am relying on this as a fallback for any 404's, it seems to work
skip_files:
- ^(.*/)?#.*#$
- ^(.*/)?.*~$
- ^(.*/)?.*\.py[co]$
- ^(.*/)?.*/RCS/.*$
- ^(.*/)?\..*$
- node_modules/*
- grunt/*
- Gruntfile.js
- less/*
- lib/*
Here is my main.py it is just the default that google gives you
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
class MainHandler(webapp.RequestHandler):
def get (self, q):
if q is None:
q = 'index.html'
path = os.path.join (os.path.dirname (__file__), q)
self.response.headers ['Content-Type'] = 'text/html'
self.response.out.write (template.render (path, {}))
def main ():
application = webapp.WSGIApplication ([('/(.*html)?', MainHandler)], debug=True)
util.run_wsgi_app (application)
if __name__ == '__main__':
main ()
So when I go to localhost:8000 I get to the home page just fine. I click a link to go to other and I end up at localhost:8000/a or /b etc. If I copy and paste that link into another tab I end up at localhost:8000. I put breakpoints in the run and config block and the url hasn't changed by the time it gets there, so I am 90% sure its not the servers problem, but I have no idea what it could be. I did have the issue before where I would go to /a and it would return an error cannot get /a. So I fixed that with the serve up index all the time change, which is why I am fairly confident I set up the server correctly.
As far as I can tell from all my research this should just work without any configuration other than this on the angular side. Also like I said I can navigate within my app just fine, so it seems like my states are set up correctly.
Only SO questions I could find with similar problems did not seem to apply unless I'm missing something. 1 is about the serve up index issue I fixed and the other he was missing a '/' which I don't think I am.
How can I go directly to a state with ui-router without first navigating to index.html
Can't navigate to ui-router state with URL
In case anyone is wondering the issue was the regex format is messed up
//this is wrong
url: '/{abc:[a|b|c|d]}'
//this is right
url: '/{abc:a|b|c|d}'
I'm thinking it was working fine internally because I have the ui-sref bound to the state and when I tried to copy and paste a url it was relying on matching the url. Either way its finally working

Categories