m.o m.o - 7 months ago 90
Javascript Question

ui-route in AngularJS showing empty page

I am trying to learn AngularJS by following this tutorial: https://thinkster.io/mean-stack-tutorial.

I got up to the part right before it says "Creating New Comments". The problem I'm having is that when I click "Comments", a blank page appears with just a horizontal line.

It was my understanding that the title of the post should be on top with the two fake comments. Here's my code:

index.html:

<!DOCTYPE html>
<html>
<head>
<title>Flapper News</title>

<!-- BOOTSTRAP -->
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">

<!-- ANGULARJS -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="app.js"></script>

<style> .glyphicon-thumbs-up { cursor:pointer } </style>
</head>

<body ng-app="flapperNews" style="padding: 50px">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>

<!-- Inline home template -->
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>

<!-- Show all the posts -->
<div ng-repeat="post in posts | orderBy: '-upvotes'" style="margin-bottom: 10px;">

<div class="row">
<div class="col-md-2" style="width: 80px;">
<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)"></span>
&nbsp;&nbsp;{{post.upvotes}}
</div>

<div class="col-md-9">
<span style="font-size:20px;">
<a ng-show="post.link" href="{{post.link}}">{{post.title}}</a>
<span ng-hide="post.link">{{post.title}}</span>
</span>

<br />
<span style="font-size: 12px;">
<a href="#/posts/{{$index}}">Comments</a> l
<a href="#/posts/{{$index}}">Share</a>
</span>
</div>
</div>
</div>

<!-- Form to make new posts -->
<form ng-submit="addPost()" style="margin-top:30px;">
<h3>Add New Post</h3>

<div class="form-group">
<input type="text" class="form-control" placeholder="Title" ng-model="title" />
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Link" ng-model="link" />
</div>

<button type="submit" class="btn btn-primary" ng-click="submit">Post</button>
</form>
</script>

<!-- Inline Posts section -->
<script type="text/ng-template" id="/posts.html">

<!-- Display title as header -->
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">{{post.title}}</a>
<span ng-hide="post.link">{{post.title}}</span>
</h3>
</div>

<!-- Display the comment -->
<div ng-repeat="comment in post.comments | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(comment)"></span>
{{comment.upvotes}} - by {{comment.author}}
<span style="font-size:20px; margin-left:10px;">{{comment.body}}</span>
</div>
</script>
</body>
</html>


app.js

var app = angular.module('flapperNews', ['ui.router']);

app.factory('posts', [function() {
var o = {
posts: []
};

return o;
}]);

app.config([
'$stateProvider',
'$urlRouterProvider',

function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl'
});

$stateProvider
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
});

$urlRouterProvider.otherwise('home');
}]);

app.controller('MainCtrl', ['$scope', 'posts', function($scope, posts) {
$scope.posts = posts.posts;

$scope.addPost = function() {
if(!$scope.title || $scope.title === '') {
return;
}

$scope.posts.push({
title: $scope.title,
link: $scope.link,
upvotes: 0,
comments: [
{author: 'Joe', body: 'Cool Post!', upvotes: 0},
{author: 'Bob', body: 'Great idea but no!', upvotes: 0}
]});

$scope.title = '';
$scope.link = '';
};

$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
}

}]);

app.controller('PostsCtrl', [
'$scope',
'$stateParams',
'posts',
function($scope, $stateParams, posts) {
$scope.posts = posts.posts['$stateParams.id'];
}]);


I'm not sure what I'm doing wrong for it to display nothing. Any help would be appreciated, thank you!

Console Errors:

The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.


Use of getPreventDefault() is deprecated. Use defaultPrevented instead.

Answer

Your code will not work because of multiple issues: 1. You are not adding any id property in addPosts() to your posts but expecting it while accessing posts.posts['$stateParams.id'].

  1. In comments template you are using post while you have declared $scope.posts in controller.

I have created a jsbin to add the id property and fix other issues and it works now.

Comments