I'm creating an app using fake JSONplaceholder API. I'm displaying a list of posts and I want the ng-repeated post titles to link to the post view.

Here's the HTML:

    <body layout="column" ng-app="myApp" ng-cloak ng-controller="controller">
    <h1>{{apptitle}}</h1>
    <script type="text/ng-template" id="allposts.htm">
        <a href="#addpost">
    <button type="button" class="btn btn-primary addbtn" ng-model="singleModel" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
        Add a post
    </button>
</a>
        View
        <select ng-model="viewby" ng-change="setItemsPerPage(viewby)">
            <option>9</option>
            <option>18</option>
            <option>36</option>
            <option>100</option>
        </select>posts
        <div class="row" ng-repeat="collatedPostList in collatedPosts">
            <div class="onepost col-xs-4 box" ng-repeat="post in collatedPostList">
                 <div class="inner">
                <a href="#/posts/{{post.indexOf(post)}}">{{post.title}}</a>
                <p>{{post.body | limitTo: 60}}{{post.body.length < 20 ? '' : '...'}}</p>
            </div>
            </div>
        </div>
        <div class="text-center">
        <ul uib-pagination total-items="totalItems" ng-model="currentPage" class="pagination-sm"
            items-per-page="itemsPerPage" ng-change="pageChanged(currentPage)"></ul>
        </div>
    </script>
    <script type="text/ng-template" id="posts.htm">
  </script>
    <script type="text/ng-template" id="addpost.htm">
    <form ng-submit="addPost()" class="adding">
        <input id="titleadd" type="text" name="title" ng-model="newPost.title" placeholder="Add title">
        <br>
        <input id="textadd" type="text" name="body" ng-model="newPost.body" placeholder="Add some text">
        <br>
        <button type="submit" ng-click="addAlert(msg,'success')" class="btn btn-primary" id="submit" value="Submit">
        Post it
        </button>
        <a href="#allposts">
        <button type="button" class="btn btn-primary" >
            Go back to post list
        </button></a>
            <br>
        <uib-alert 
              ng-repeat="alert in alerts" 
              type="{{alert.type}}" 
              dismiss-on-timeout="5000" 
              close="alerts.splice($index, 1);">{{alert.msg}}
    </uib-alert>    </form>
  </script>
    <div ng-view></div>
    <script src="app.js"></script>
</body>

and JS:

Array.prototype.collate = function(collateSize) {
    var collatedList = [];

    if (collateSize <= 0) {
        return [];
    }
    angular.forEach(this, function(item, index) {
        if (index % collateSize === 0) {
            collatedList[Math.floor(index / collateSize)] = [item];
        } else {
            collatedList[Math.floor(index / collateSize)].push(item);
        }
    });

    return collatedList;
};

var myApp = angular.module('myApp', ['ngRoute', 'ui.bootstrap']);

myApp.config(function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: 'allposts.htm',
        controller: 'PostsController'
    }).when('/posts', {
        templateUrl: 'posts.htm',
        controller: 'PostController'
    }).when('/addpost', {
        templateUrl: 'addpost.htm',
        controller: 'AddController'
    }).otherwise({
        redirectTo: '/'
    });
});

myApp.controller('PostsController', function($scope) {});

myApp.controller('PostController', function($scope) {});

myApp.controller('AddController', function($scope) {});


myApp.controller('controller', function($scope, $http) {
    $scope.apptitle = "My app";

    $http({
        method: 'GET',
        url: "http://jsonplaceholder.typicode.com/posts"
    }).then(function(response) {
        $scope.posts = response.data;
        $scope.viewby = 9;
        $scope.totalItems = $scope.posts.length;
        $scope.currentPage = 1;
        $scope.itemsPerPage = $scope.viewby;
        $scope.maxSize = 5;
        $scope.collatedPosts = getCollatedPosts($scope.posts);
        $scope.newPost = {};


    function getCollatedPosts(posts) {
        if (!posts) {
            return [];
        }

        var paginatedPosts = posts.slice((($scope.currentPage - 1) * $scope.itemsPerPage), (($scope.currentPage) * $scope.itemsPerPage));
        return paginatedPosts.collate(3);
    }

    $scope.setPage = function(pageNo) {
        $scope.currentPage = pageNo;
    };

    $scope.setItemsPerPage = function(num) {
        $scope.itemsPerPage = num;
        $scope.currentPage = 1; //reset to first page
        $scope.collatedPosts = getCollatedPosts($scope.posts);
    };

    $scope.pageChanged = function(currentPage) {
        $scope.currentPage = currentPage;
        $scope.collatedPosts = getCollatedPosts($scope.posts);
    };
        $scope.addPost = function(){
          $http.post("http://jsonplaceholder.typicode.com/posts",{
            title: $scope.newPost.title,
            body: $scope.newPost.body,
            usrId: 1
          })
          .success(function(data, status, headers, config){
            console.log(data);
            $scope.posts.push($scope.newPost);
            $scope.newPost = {};
          })
          .error(function(error, status, headers, config){
            console.log(error);
          });
    };});


    $scope.alerts = [];

    $scope.msg = "Well done! Your post was added";

    $scope.addAlert = function(msg, type) {
      $scope.alerts.push({
        msg: msg,
        type: type
      });
    };

});

My code is not working. There is 100 ng-repeated posts and I want each post title to link to the post view. Current code links every title to #/posts. I also tried <a href="#/posts/{{post.id}}">{{post.title}}</a>, but with no success. What is the correct way to do this?

You can see full code here:

share|improve this question
    
doesn't work with that either – summerfreeze 2 hours ago
    
do I have to change something in the route provider? – summerfreeze 2 hours ago
1  
inspect the repeated element and check the href value – Sunil Garg 2 hours ago
    
I created a codepen: codepen.io/summerfreeze/pen/ORVQYz – summerfreeze 1 hour ago

You can debug the code by following way.

console.log(response.data) // will give you data in success http get

then

you can print those data in HTML by {{posts}}, if you get the data there, you're on the right track.

Please try my following snippet to link the posts

var myApp = angular.module('myApp', []);
myApp.controller('PostController', ['$scope','$http', function($scope, $http) {
  var root = 'http://jsonplaceholder.typicode.com';
  
  $http({
    method: 'GET',
    url: root+'/posts'
  }).then(function successCallback(response) {
     $scope.posts= response.data;
  }, function errorCallback(response) {
    
  });
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="PostController">
  <div ng-repeat="post in posts track by $index">
    <a ng-href="http://jsonplaceholder.typicode.com/posts/{{post.id}}">{{post.title}}</a> <br/>
  </div>
</div>

share|improve this answer
    
but you're getting the data directly from the API, I want it to be displayed as a view – summerfreeze 2 hours ago
    
Can you create jsfiddle to know the exact problem? – Loading.. 2 hours ago
    

First i write your route provider like this :

myApp.config(function($stateProvider, $routeProvider) {
    $routeProvider.otherwise('/posts');

    $stateProvider.state('posts', {
      url: '/posts',
      templateUrl: 'allposts.htm',
      controller: 'PostsController'
    }).state('posts.detail', {
      url: '/:postId',
      templateUrl: 'posts.htm',
      controller: 'PostController'
    }).state('posts.add', {
      url: '/add',
      templateUrl: 'addpost.htm',
      controller: 'AddController'
    });
});

Then to create your link you can do :

<a ui-sref="posts.detail({postId: post.id})">{{ posts.title }}</a>
share|improve this answer
    
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to: TypeError: $routeProvider.state is not a function – summerfreeze 2 hours ago
    
I created a codepen: codepen.io/summerfreeze/pen/ORVQYz – summerfreeze 1 hour ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.