2

I am created an AngularJS app and am creating a service that provides the user a link like localhost:8080/sync/03afdbd66e7929b1 which they are supposed to share with people and will bring them to a form. However, after I setup the route to handle this request like so:

app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider){
    $routeProvider
        .when('/',
        {
            templateUrl : 'views/home.html',
            controller : 'mainCtrl'
        })
        .when('/about',
        {
            templateUrl : 'views/about.html',
            controller : 'mainCtrl'
        })
        .when('/begin',
        {
            templateUrl : 'views/sync.html',
            controller : 'syncCtrl'
        })
        .when('/sync/:id', {
            templateUrl : 'views/form.html',
            controller : 'formCtrl'
        })
        .otherwise({
            redirectTo : '/'
        });

    if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }

}]);

and create a view called form.html, then when I try to go to the link above, all of a sudden all of my JavaScript files are filled with my index.html and I have the following javascript errors:

Uncaught SyntaxError: Unexpected token < app.js:1
Uncaught SyntaxError: Unexpected token < routes.js:1
Uncaught SyntaxError: Unexpected token < controllers.js:1
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.3.0-beta.9/$injector/modulerr?p0=syncIt&p1=Er…arjs.org%2F1.3.0-beta.9%2F%24injector%2Fnomod%3Fp0%3DsyncIt%0A%20%20%20%20...<omitted>...5) angular.js:3

This is because all of these .js files are now

<!DOCTYPE html>
<html lang="en">
    <head>
    <title>DaemonDeveloper</title>
        <link href='http://fonts.googleapis.com/css?family=Dosis:400,600,800' rel='stylesheet' type='text/css'>


    <style>
        body, html {
            margin:0;
            padding:0;
            background:#fff;
            font-family:verdana;
            color:#3DEB94;
        }
        h1, h2, h3, h4, h5, h6 {
            margin:0;
            padding:0;
            font-family: 'Dosis', sans-serif;
            color:inherit;
        }
        nav {
                position:relative;
                left:0;
                top:0;
                background:#fff;
                width:100%;
                min-width: 960px;
        }
        a {
            text-decoration: none;
        }
        #app {
            min-width: 960px;
        }

        #nav-wrap {
            list-style: none;
            display:block;
            margin:0;
            padding:0;
        }
        .nav-item {
            display:inline-block;


        }
        .nav-item > a {
            text-decoration: none;
            text-transform: uppercase;
            color:#3DEB94;
            font-size:22px;
            font-family: 'Dosis', sans-serif;
            padding:15px 25px;
            display:inline-block;

        }
        .nav-item > a:hover {
            color:#fff;
            background:#3DEB94;
            cursor:pointer;
        }


        #banner {
            width:100%;
            text-align: left;
            background:#3DEB94;
            color:#fff;
        }
        #banner > h1 {
            font-size:72px;
            padding-left:50px;
            line-height:150px;
            font-weight:400;
            display:inline;
        }
        #banner > h2 {
            padding-left:200px;
            line-height: 150px;
            display:inline;
            font-weight: 600;
            letter-spacing: 1.25px;
        }


        #step-list {
            width:100%;
            position:relative;
        }
        .step {
            width:100%;
            color:#fff;
        }
        .step:nth-child(odd) {
            background:#3DEB94;
            color:#fff;
        }
        .step:nth-child(even){
            background:#fff;
            color:#3DEB94;
        }

        .step-text {
            text-align: center;
            line-height: 350px;
            font-size:60px;
            font-weight: 400;

        }
        .step-start {
            display:block;
            margin:100px auto;
            font-size:60px;
            background-color:#fff;
            color:#3DEB94;
            border:4px solid #3DEB94;
            padding:25px;
            border-radius:25px;
            -webkit-transition:background-color 1s;
            -webkit-transition:color 1s;

        }
        .step-start:hover {
            background-color:#3DEB94;
            color:#fff;
            border:4px solid #fff;
        }
        #sync-link {
            padding:35px 50px;
            background:#DEDEDE;
            margin:0 auto;
            border-radius: 12px;

            -moz-box-shadow:   inset 0 0 15px #adadad;
             -webkit-box-shadow: inset 0 0 15px #adadad;
             box-shadow:         inset 0 0 15px #adadad;
             color:#adadad;
        }

        .view {
            background:#fff;
            color:#3DEB94;
            width:960px;
            position: relative;
            margin:0 auto;
        }
        .xlarge-text {
            font-size:52px;
            font-weight: 400;
            padding:62px 0;
        }
        .large-text {
            font-size: 42px;
            font-weight: 400;
            padding:50px 0;
        }
        .med-text {
            font-size:32px;
            font-weight: 400;
            padding:35px 0;
        }
        .center {
            text-align: center;
        }
        .active {
            color:#fff !important;
            background:#3DEB94;
        }
        .invisible {
            opacity: 0;
            transition: opacity 1s;
        }
        .success {
            color:green;
        }
        .failure {
            color:red;
        }


        .input {
            padding:12px;
            font-size:22px;
            border-radius:8px;
            border: 3px solid #3DEB94;
        }
        input:focus, button:focus {
            outline:none;
        }
        .sync-btn {
            padding:12px;
            border:3px solid #3DEB94;
            font-size:22px;
            background:#fff;
            color:#3DEB94;
            border-radius:8px;
        }

        #identifier {
            margin-bottom:150px;
        }
    </style>
    </head>
    <body ng-app="syncIt">
        <section id="banner">
            <h1>sync.it</h1>
            <h2>Test</h2>
        </section>
        <nav>
            <ul id="nav-wrap">
                <li class="nav-item"><a href="/">Home</a></li>
                <li class="nav-item"><a href="/begin">Begin</a></li>
                <li class="nav-item"><a href="/about">About</a></li>
            </ul>
        </nav>
        <section id="app" ng-view>

        </section>


            <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
            <script src="https://code.angularjs.org/1.3.0-beta.9/angular.min.js"></script>
            <script src="https://code.angularjs.org/1.3.0-beta.9/angular-route.js"></script>
            <script>
                $(document).ready(function(){
                    $('.nav-item').click(function(){
                        $('.nav-item > a').removeClass('active');
                        $(this).children('a').addClass('active');
                    })
                })
            </script>

            <script src="content/app.js" type="text/javascript"></script>
            <script src="content/routes.js" type="text/javascript"></script>
            <script src="content/controllers.js" type="text/javascript"></script>

    </body>
</html>

There is some kind of weird routing going on here and I can't figure out why it is just this route and whether or not it is an Angular problem or a Node problem.

12
  • Is there a route handler in nodejs first which handles the /sync/id url? Commented May 22, 2014 at 0:53
  • 1
    Post your node.js routing code somewhere. It sounds like you're missing static assert serving middleware like express.static() or it's misconfigured. Commented May 22, 2014 at 0:54
  • ok here are my node routes pastebin.com/yySTEq6A. I tried to make it so that any non API calls just render the Angular app, which works for everything else except this route Commented May 22, 2014 at 1:01
  • 1
    You don't have a static route in your node configuration for the content/* route. Therefore the request for the javascript files is falling through to the default route, and returning index.html for each of them. Commented May 22, 2014 at 1:28
  • Why does it work completely fine for every other route then? Commented May 22, 2014 at 1:36

2 Answers 2

2

The problem is that your script references are relative. When you directly access a /sync url (not dynamically on the client using Angular), the request for content/app.js is falling to the node config for index.html. With this config, the dynamic routing would be fine, because the path works when you initially access any file in the root, such as /index.html.

Change your script references to be relative to the root.

        <script src="/content/app.js" type="text/javascript"></script>
        <script src="/content/routes.js" type="text/javascript"></script>
        <script src="/content/controllers.js" type="text/javascript"></script>

And change your Angular route template path to start with '/', like this:

    .when('/sync/:id', {
        templateUrl : '/views/form.html',
        controller : 'formCtrl'
    })
Sign up to request clarification or add additional context in comments.

2 Comments

After I did change that, now my site is in an infinite loop of requests for the JS files and the page just crashes.
looping caused by relative path that doesn't start with '/' in your angular routing. Updating the answer.
-1

The way your server is written, the route responds to a querystring, not a parameter, so it's not being triggered on your API call. /sync?nameId=03afdbd66e7929b1 for example. You need to change:

app.get('/api/sync', function(req, res){){
    var nameId = req.query.nameId;

to this:

app.get('/api/sync/:nameId', function(req, res){){
    var nameId = req.params.nameId;

1 Comment

my app.get('/api/sync') is a completely different thing then what I am trying to do. That is an API call. The /sync/03afdbd66e7929b1 is supposed to just change the Angular view

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.