0

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:

10
  • Should that be <a href="#!/posts/{{post.id}}"> - it looks like you left out the exclamation point in the #!. Commented Sep 8, 2016 at 7:57
  • It doesn't work either. Why is the exclamation point needed? Commented Sep 8, 2016 at 8:00
  • Can you try this??<div class="onepost col-xs-4 box" ng-repeat="post in collatedPostList track by $index"> <div class="inner"> <a href="#/posts/{{$index}}">{{post.title}}</a> <p>{{post.body | limitTo: 60}}{{post.body.length < 20 ? '' : '...'}}</p> </div> Commented Sep 8, 2016 at 8:03
  • It doesn't work Commented Sep 8, 2016 at 8:05
  • Maybe I have to change something in the route provider? Commented Sep 8, 2016 at 8:05

1 Answer 1

2

Do following changes::

Codepen :http://codepen.io/ruhul/pen/mAJLEo

1) Remove "/" from your href and use post.id (I believe on a click of link, you will be doing some of the database calls based on postID and will render it to UI ).

<div class="onepost col-xs-4 box" ng-repeat="post in collatedPostList track by $index"> <div class="inner"> <a href="#/posts/{{post.id}}">{{post.title}}</a> <p>{{post.body | limitTo: 60}}{{post.body.length < 20 ? '' : '...'}}</p> </div>

2) As you are passing parameter add your routing configuration as below:: You can later use this parameter in controller using $routeParams.

.when('/posts/:postId', { templateUrl: 'posts.htm', controller: 'PostController' })

3) Change your controller to this::

myApp.controller('PostController', function($scope,$routeParams,$http) {
  console.log($routeParams.postId)
   $http({
        method: 'GET',
        url: "http://jsonplaceholder.typicode.com/posts/"+$routeParams.postId
    }).then(function(response) {$scope.post=response.data});
});
Sign up to request clarification or add additional context in comments.

10 Comments

that solution gives a blank page
btw, where is "postID" from?
{{post.id}} part form your url will be mapped to postID, e.i if your url is #/posts/1 , postID=1. In controller $routeParams.postID will give you 1.
See my edited answer....follow all three steps and it should work, It is working for me.
see my code pen codepen.io/ruhul/pen/mAJLEo it is working fine...only #/posts/{{$index}} can cause problem..double check..clear the browser and retest it.
|

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.