1

So I am using Node.JS with Express as my backend and my servlet for API. I'm using AngularJS as my front end.

Through many Google searches, I finally solved my problem of using ngRoute with AngularJS and Node.js. And ended up with this:

var index = require('./routes/index');
var auth  = require('./routes/auth');

var app = express();

app.set('views', path.join(__dirname, 'views'));

app.use('/api/auth', auth);
app.use('/', index);
app.use('*', index);

This is of course an excerpt of my app.js file at the root of my project.

Now when I make a call to my /api/auth/ I get told that node.js can't find my view. If I remove the app.use('*', index) the API works again but 'ngRoute' doesn't work.

How can I get to a point where both are working together? I also want to keep the address bar url as clean as possible.

My project was started with a call to yo node using yeoman if that helps any in the file/folder structure of my application.

Update

I'm not getting any answers or comments so maybe providing my full app.js file will be helpful and help me figure this out. Here it is.

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var auth = require('./routes/auth');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/api/auth', auth);

app.use('/', index);
app.use('*', index);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handler
app.use(function(err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;

Update 2

I have come to notice that the statement "ngRoute doesn't work" is vague. If I remove app.use('*', index) I receive this error if I try to go to an address other than the base address. I also receive this error when trying to access theapi/auth

Error: Failed to lookup view "error" in views directory "/Users/mitch/websites/splatform/views"

Update 3

The index.js file that my routes in app.js refer to includes this as well.

app.get('/', function(req, res, next) {
    res.sendFile(path.join(__dirname, '../', 'views', 'index.html'));
});

But, API calls shouldn't be going to the index.js File. Should be going to Auth.js.

Update 4

As requested, here is my $routeProvider from AngularJS.

$routeProvider
            .when('/', {
                templateUrl: 'templates/home.html',
                resolve: {
                    lazy: ['$ocLazyLoad', function($ocLazyLoad) {
                        return $ocLazyLoad.load ('frontStyles');
                    }]
                }
            })
            .when('/app/login', {
                templateUrl: 'templates/login.html',
                resolve: {
                    lazy: ['$ocLazyLoad', function($ocLazyLoad) {
                        return $ocLazyLoad.load ('appStyles', 'appScripts');
                    }]
                }
            })
            .when('/app/dashboard', {
                templateUrl: 'templates/dashboard.html',
                resolve: {
                    lazy: ['$ocLazyLoad', function($ocLazyLoad) {
                        return $ocLazyLoad.load ('appStyles', 'appScripts');
                    }]
                }
            })
            .otherwise({ redirectTo: '/' });

        $locationProvider.html5Mode(true);

Also here is a simple run down of my file structure

app.js
routes
  --auth.js
  --index.js
views
  --index.html ( angularJS Base )
public
  --directives
  --fonts
  --images
  --javascripts
  --stylesheets
  --templates ( Views that angularjs uses in `ng-view`
  • This is a ***very well documented*** process. There have been many questions almost identical to this posted here. What *specifically* makes your question different from any of those? Also, what does "ngRoute doesn't work" actually mean? Error messages? unexpected behavior? – Claies Jan 02 '17 at 16:57
  • I spent all day yesterday googling for results. Tried multiple instances and nothing seemed to make it "work" (ngroute didn't work or api didn't work). "ngRoute doesn't work" means when I try to go anywhere other than the base address ('/') such as ('/login') I get an error that states the view couldn't be found. – user7366018 Jan 02 '17 at 17:03
  • what is the path to one of the view files? – Claies Jan 02 '17 at 17:03
  • also, I assume that you are using `html5Mode` in Angular? you haven't really shown any of your angular code.... – Claies Jan 02 '17 at 17:05
  • @Claies the path of the view files if /views/ however the view path for angularjs is /public/templates/ The only file in /views/ is the base index.html for Angularjs – user7366018 Jan 02 '17 at 17:06
  • @Claies I do apologize, I am trying to help as much as possible. Yes, I am using `html5Mode` in Angular. – user7366018 Jan 02 '17 at 17:07
  • it doesn't look like you have an express route for the template files. You may want to take a look at this FAQ from the 3rd party ui-router. It's not *specifically* about ng-route, but ui-router is a drop in replacement, so if it works for ui-router, it will definitely work with ng-route. https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode – Claies Jan 02 '17 at 17:09
  • also, http://briantford.com/blog/angular-express – Claies Jan 02 '17 at 17:09
  • Check my updated question. – user7366018 Jan 02 '17 at 17:14
  • Also, I shouldn't need a specific route for template files as they are listed in public. My css/javascript/images etc are all in public and they work just fine? – user7366018 Jan 02 '17 at 17:15
  • again, you aren't showing any angular code here, so it's not obvious what files angular is trying to request from the server. clearly you have a bit of confusion about it yourself, since you said that your angular templates are in `/public/templates`, but the error you have in the question suggests angular was requesting a file from `/views`... – Claies Jan 02 '17 at 17:17
  • @Claies No need to get snarky, I'm trying to help so I can learn. I've updated my question with some angular code and a base file structure. – user7366018 Jan 02 '17 at 17:24
  • So what address did you go to that generated `Error: Failed to lookup view "error" in views directory "/Users/mitch/websites/splatform/views"`? None of the angular code you listed here should be causing an `error` view to be loaded? – Claies Jan 02 '17 at 17:27
  • Copied directly from the address bar: http://localhost:3000/app/login – user7366018 Jan 02 '17 at 17:27
  • and don't you want `/public/templates/home.html` (for example), rather than `templates/home.html`? – Claies Jan 02 '17 at 17:28
  • `app.use(express.static(path.join(__dirname, 'public')));` in the `app.js` file grabs it and directs it accordingly. – user7366018 Jan 02 '17 at 17:33
  • @Claies I tried adding public/ to my `$routeProvider` and it changed nothing. – user7366018 Jan 02 '17 at 17:45
  • It actually wasn't a problem with routing at all. Just issues with error reporting and what Node.js was returning to angular. Should I delete this question or what? – user7366018 Jan 02 '17 at 19:46
  • Hello! Have you found solution for this? – Natan Bueno Nov 05 '19 at 15:30

1 Answers1

0

Call api's routes first then angularjs index.

For example: routesWeb.js

    'use strict';
    var express = require('express');
    var path = require('path');

    module.exports = function(app) {

        var path_web = path.resolve(__dirname, '..');
        var path_origin = path.resolve(__dirname, '../../');

        app.use('/scripts',express.static(path_web + '/scripts'));
        app.use('/pages',express.static(path_web + '/pages'));
        app.use('/node_modules',express.static(path_origin + '/node_modules'));

        app.route('/*')
        .get(function(req, res){
            res.sendFile(path_web + '/pages/ng-index.html');
        });
    }

pessoaRota.js

'use strict';
module.exports = function(app) {

    var pessoasCtrl = require('../controllers/pessoasController');  

    app.route('/api/pessoas')
        .get(pessoasCtrl.obter_todos_pessoas);

    app.route('/api/pessoas/:pessoaId')
        .get(pessoasCtrl.obter_pessoa_por_id);

    app.route('/api/pessoasFeias')
        .get(pessoasCtrl.obter_pessoas_feias);

};

server.js

var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
app.use(bodyParser.json());
app.use(cookieParser());


var server = app.listen(port, function(){
    var host = server.address().address;
    var port = server.address().port;
    console.log("Aplicação está on nesse endereço http://%s:%s", host, port)
});

require('./api/routes/pessoaRota.js')(app);
require('./web/routes/routesWeb.js')(app);

For more go here.

tomerpacific
  • 4,704
  • 13
  • 34
  • 52