Suggestion Box - problem with hashing anchors/routing - need help


#1

Hello, I started Suggestion Box project and everything went easy until i started adding routing to my app. I'm using Brackets as my text editor, and its Live Preview option makes local server where i can run the app.
index.html:

<!DOCTYPE html>
<html>
    <head>
        
        <title>Suggestion Box</title>
        <link rel="stylesheet" type="text/css" href="css/main.css">
        <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/
css/bootstrap.min.css" rel="stylesheet"> 
        <script type="text/javascript" src="js/vendor/angular.min.js"></script>
        <script src="https://code.angularjs.org/1.2.28/angular-route.min.js" type="text/javascript"></script>
    </head>
    <body ng-app="SuggestionBox">
        <div ng-view></div>
        
        <!-- Modules  -->
        <script src="js/app.js"></script>
        <!-- Controllers  -->
        <script src="js/controllers/HomeController.js"></script>
        <script src="js/controllers/SuggestionController.js"></script>
        <!-- Services -->
        <script src="js/services/suggestions.js"></script>
    </body>
</html>

home.html:

<div>
<h1>{{ helloWorld }}</h1>
<a href="#/about">About</a>
        <div ng-repeat="post in posts | orderBy: '-upvotes'">
            <p>{{ post.title }}</p>
            <!-- <p>{{ post.upvotes }}</p> -->
            <p><span class="glyphicon glyphicon-plus-sign" ng-click="upVote(post)"></span> Upvotes: {{post.upvotes}}</p>
            <a href="#/suggestion/{{$index}}" target="_self">Comments</a>
        </div>
        
        <form ng-submit="addSuggestion()" style="margin-top: 50px">
          <h3> Submit Your Suggestion </h3>
          <div class="form-group">
            <input type="text" class="form-control" placeholder="Great ideas here" ng-model="title"></input>
          </div>
          <button type="submit" class="btn btn-primary">Suggest</button>
        </form>
</div>

My app.js file:

var app = angular.module("SuggestionBox", ['ngRoute']);
app.config(["$routeProvider", function($routeProvider){
    $routeProvider
    .when('/',{
        controller: "HomeController",
        templateUrl: "views/home.html"
    })
    .when('/suggestion/:id',{
        controller: "SuggestionController",
        templateUrl: "views/suggestion.html"
    })
    .when('/about', {
        controller: "AboutController",
        templateUrl: "views/about.html"
    })
    .otherwise({
        redirectTo: '/'
    });
}]);

HomeController.js:

app.controller("HomeController", ["$scope", "suggestions", function($scope, suggestions){
    $scope.helloWorld = "Hello Angular JS!";
    $scope.posts = suggestions.posts;
    $scope.addSuggestion = function(){
      if(!$scope.title || $scope.title === ""){
          return;
      } 
      $scope.posts.push({
          title: $scope.title,
          upvotes: 0,
          comments: []
      });
      $scope.title = ""; //clearing input
    };
      $scope.upVote = function(post){
      post.upvotes += 1;  
    };
}]);

SuggestionController:

app.controller("SuggestionController", ["$scope", "$routeParams", "suggestions", function($scope, $routeParams, suggestions){
    $scope.post = suggestions.posts[$routeParams.id].comments;
    $scope.addComment = function(comment){
        $scope.post.push(comment);
    }
    $scope.hello = "Hello comments";
}]);

In my index.html everything is included, no console error occur, i got ng-view set up correctly, because
when i run Live Preview the url in browser is http://127.0.0.1:57983/index.html#!/ and it shows views/home.html template correctly. My problem starts when i click certain comment.
When i click first one the url changes to: http://127.0.0.1:57983/index.html#!/#%2Fsuggestion%2F0
When i click first one the url changes to: http://127.0.0.1:57983/index.html#!/#%2Fsuggestion%2F1
When i click first one the url changes to: http://127.0.0.1:57983/index.html#!/#%2Fsuggestion%2F2

etc. but NOTHING HAPPENS. The url changes as expected but the view doesnt change at all. However, if I manually change the url in the browser, let's take the first example, for http://127.0.0.1:57983/index.html#!/suggestion/0 it shows exactly the template i want. Has anybody come accross this problem already? I tried some different solutions already, for example using $locationProvider. i used html5mode(true); and tried changing the anchor links. Tried using target="_self" in anchors. Even tried not using $locationProvider and even disabling bootstrap which might use it. It always redirects to some hashed link and nothing happens, only manual exact input. Do you think it might be a problem with Brackets' Live Preview specifics? The server or something?

Everytime i check angular js codecademy projects i come to conclusion i got everything following the same pattern. And yet the linking to another view still doesn't work. :cry:


#2

Dumb question.. Do you have this path in your local setup? You could just call the same CDN as the next script and have a current version.


#3

No question are dumb, take any question you want. If i hadn't it on my local setup there would be console errors. I have it downloaded and it sits in js/vendor file under the angular.min.js name.

I see all the demo suggestions in the main view. just when i click on one of them only the url changes - the view does not :frowning:


#4

Can I pester you for a link to this project, please? I need to get a closer look. Thanks.


#5

should i upload whole project folder and post a link here? or should i copy paste every file? i know there's thing called GitHub, but I didn't use it yet tho. Just tell me your preference and I'll gladly do it :slight_smile:


#6

Nothing so detailed. I only need to see the course page.


#7

https://www.codecademy.com/final_project/learn-angularjs

It's the final project


#8

We seem to be missing the suggestions.js service. Do you have that?


#9

suggestions.js

app.factory('suggestions', [function(){
  var demoSuggestions = {
    posts: [
      {
        title: 'Free pizza at club meetings',
        upvotes: 15,
        comments: ['is it free tho?', 'nice!']
      },
      {
        title: 'End all club emails with Laffy Taffy jokes',
        upvotes: 9,
        comments: ['he he hu he hu ha ha', 'holy christ']
      },
      {
         title: 'Retrofit water fountain with Gatorade',
         upvotes: 3,
         comments: ['holy moly', 'stupid idea']
      },
      {
         title: 'Sing Bon Jovi\'s "Living on a Prayer" halfway through meetings',
         upvotes: 7,
         comments: ['not funny']
      }
    ]
  };
  return demoSuggestions;
}]);

I know my comments are so creative.

When i hit Live Preview in Brackets the url in browser is http://127.0.0.1:63443/index.html#!/ and i see all the comments - just as expected. Before i used routing, the ng-repeat part was in index.html and the look of my app was exactly the same. The problem is only when i click on a comment or 'about'. Then the url change (gave examples in 1st post) but the view doesn't change at all. Only when i input http://127.0.0.1:63443/index.html#!/suggestion/0 or http://127.0.0.1:63443/index.html#!/suggestion/"here put comment index.." i see the view i want to see, which is the array of posts' comments.


#10

I'm a little mystified by the ! in that URL, but may have just forgotten some basics. Haven't done any AngularJS in ages. I was sure I had done this but cannot find it on this machine. Must be on the laptop.

Could be I've stared at this code for too long to be objective anymore. Time for someone else to chime in and relieve me. Gotta go. Sorry I couldn't be of any help.


#11

http://www.megafileupload.com/p222/main.css
http://www.megafileupload.com/p223/index.html
http://www.megafileupload.com/p224/app.js
http://www.megafileupload.com/p225/AboutController.js
http://www.megafileupload.com/kPT4/HomeController.js
http://www.megafileupload.com/kPT5/SuggestionController.js
http://www.megafileupload.com/8fs0/suggestions.js
http://www.megafileupload.com/8fs1/angular.min.js
http://www.megafileupload.com/8fs2/about.html
http://www.megafileupload.com/8fs3/home.html
http://www.megafileupload.com/8fs4/suggestion.html

these all all the files. The directories on my computer are:
index.html
css/main.css
js/app.js
js/vendor/angular.min.js
js/controllers/AboutController.js
js/controllers/SuggestionController.js
js/controllers/HomeController.js
js/services/suggestions.js
views/home.html
views.about.html
views/suggestion.html

There's all the files if anyone is interested in the case. Thanks for effort!


#12

I would prefer to just copy and paste from here, if it's all the same. We're still missing,

SuggestionBox.js // edited.
about.html
AboutController.js

Add to that,

suggestion.html


#13

AboutController.js

app.controller("AboutController", ["$scope", function($scope){
     $scope.testMessage = "test";
}]);

about.html:

<div><h1>{{ testMessage }}</h1></div>

suggestion.html

<div>
    <h1> {{ post }}</h1>
</div>

#14

I found a solution! I will later edit this post to tell everybody the solution, maybe one day it will help some one. Special thanks to @mtf for effort!

EDIT:
The whole problem was caused by one thing. I had the newest angular 1 version. I believe codecademy didn't use the newest. In version i downloaded - 1.6.1 they decided to set $locationProvider.hashPrefix('"!");
which was the cause of my problem.. My fix was to use $locationProvider.hashPrefix(""); Now it works like a charm. Please close the topic and leave it so somebody in the future could use it :). Here is my fixed code:
js/app.js:

var app = angular.module("SuggestionBox", ['ngRoute']);
app.config(["$routeProvider", "$locationProvider", function($routeProvider, $locationProvider){
    $locationProvider.hashPrefix('');
    $routeProvider
    .when('/home',{
        controller: "HomeController",
        templateUrl: "views/home.html"
    })
    .when('/suggestion/:id',{
        controller: "SuggestionController",
        templateUrl: "views/suggestion.html"
    })
    .when('/about', {
        controller: "AboutController",
        templateUrl: "views/about.html"
    })
    .otherwise({
        redirectTo: '/home'
    });
}]);

#15

Ah, so it was that nasty ! after all. That's two person-days we won't get back but I'm glad you solved it. Whew!