0

I am trying to define a simple application with login functionality in Angular2 with Typescript. I have defined my Router but am getting an error when attempting to access the url in a browser. This is the error:

Cannot GET /login

And the url I am using:

http://localhost:3012/login

It seems as if router is not correctly routing the URL to correct component and I am not sure why. Here is my home.component.ts which instantiates the app and router:

import {Component} from 'angular2/core';

import {ROUTER_DIRECTIVES, RouteConfig} from 'angular2/router';
import {LoginComponent} from './login/login.component';
import {DashboardComponent} from './dashboard/dashboard.component';

@Component({
    selector: 'home',
    templateUrl: '<router-outlet></router-outlet>',
    directives: [ROUTER_DIRECTIVES]
})

@RouteConfig([
    {path: '/login', name: 'Login', component: LoginComponent, useAsDefault: true},
    {path: '/dashboard', name: 'Dashboard', component: DashboardComponent},
    {path: '/*other', name: 'Other', redirectTo: ['Login']}
])
export class HomeComponent {

}

Both the Login and Dashboard components are defined correctly and PHPStorm has not picked up any errors.

Does anyone have any idea as to why this may be happening?

Here is my server side code. server.ts (NodeJS entry point)

import express = require('express');
import path    = require('path');

let port: number = process.env.PORT || 3012;
let app = express();

app.set('views', path.join('./src/Client/views'));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);

app.use("/node_modules", express.static(path.resolve(__dirname, '../../node_modules')));
app.use("/app", express.static(path.resolve(__dirname, '../Client/app')));

app.use("/*.html", function(req, res) {
    res.render(req.params[0] + ".html");
});

app.get('/', function(req: express.Request, res: express.Response) {
    res.render('index.html');
});

let server = app.listen(port, function() {
    let host = server.address().address;
    let port = server.address().port;
});

And my index.html file which includes all required Angular2 scripts and starts SystemJS

<html>
    <head>
        <title>Test</title>

        <script src="node_modules/es6-shim/es6-shim.min.js"></script>
        <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
        <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>

        <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
        <script src="node_modules/systemjs/dist/system.src.js"></script>
        <script src="node_modules/rxjs/bundles/Rx.js"></script>
        <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
        <script src="node_modules/angular2/bundles/router.dev.js"></script>
        <script src="node_modules/angular2/bundles/http.dev.js"></script>
        <script>
            System.config({
                packages: {
                    app: {
                        format: 'register',
                        defaultExtension: 'js'
                    }
                }
            });
            System.import('app/bootstrap')
                    .then(null, console.error.bind(console));
        </script>
    </head>

    <body>
        <home>Loading...</home>
    </body>
</html>

And my file structure:

enter image description here

Thanks

James
  • 2,800
  • 7
  • 45
  • 81
  • What server are you using to host it? It sounds like your server is trying to return the contents of directory `/login`. If you use `lite-server` this won't be an issue. Also, if you switch to `HashLocationStrategy` your URL will be `http://localhost:3012/#/login`, which your server will evaluate correctly. – Alex Kibler Jul 01 '16 at 13:10
  • What version are you on? – wolfhoundjesse Jul 01 '16 at 13:11
  • Thanks for your quick answer. I am using a custom built NodeJS server. I don't want to use lite-server as I want full control over the NodeJS layer. I can't see this being the problem as the router was working correctly before? – James Jul 01 '16 at 13:11
  • leading slash problem in routes ? – trk Jul 01 '16 at 13:14
  • I tried removing the leading slashes to no avail. – James Jul 01 '16 at 13:16
  • is there a route to /login ? I see *.html. Is your file called login.html ? – trk Jul 01 '16 at 13:18
  • Leading slashes are nor supported un the new router but in the old router they are fine. – Günter Zöchbauer Jul 01 '16 at 13:18

2 Answers2

1

I think this:

app.use("/*.html", function(req, res) {
    res.render(req.params[0] + ".html");
});

should be

app.use("/*", function(req, res) {
    res.render(req.params[0] + ".html");
});

because I am not sure why you would +.html again to a html request.

Does that solve the issue ?

trk
  • 2,106
  • 14
  • 20
  • Correct! Thanks! Can you explain further why this worked please? Thankyou very much – James Jul 01 '16 at 13:43
  • * will give any path. So, it could even be `a/b/c` but you are only fetching the first index ([0]). In the previous example that would be `a`. And, from your file organization I guessed `/login` should therefore relate to `login.html`. Therefore, I concluded `.html` should not be in your `.use` method since it is already appended within `+'.html'`. I hope I answered your doubts. – trk Jul 01 '16 at 14:02
0

I believe the router needs to have the base href set so it knows what you're routing relative to.

Angular 2 router no base href set

Community
  • 1
  • 1
  • I have set the base href but it doesn't seem to have sorted the problem. I think showing my file structure might be a good idea so I have added it. – James Jul 01 '16 at 13:27
  • the Angular2 application I am building is sat at this location within the file structure. src/Client/app. It is not sat in the root. Will this affect what I need to set the base href as? – James Jul 01 '16 at 13:37