1

I've just started using angularjs and I'm trying to connect a wordpress back-end to an Angularjs front end.

this is my index.html

<!DOCTYPE html>
<html ng-app="applicazioneIndex">
<head>
<title>AngularJS GET request with PHP</title>
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular-sanitize.min.js"></script>
  <link data-require="[email protected]" data-semver="2.3.2" rel="stylesheet" href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" />
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.0/ui-bootstrap-tpls.min.js"></script>
  <script data-require="angular-resource@*" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular-resource.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
  <meta charset="UTF-8">
</head>

  <body >

 <div class="row">
    <div class="container">  
<div ng-controller="ApplicazioneController">
      <input type="text" ng-model="searchFilter" class="form-control">
    <table class="table table-hover">
      <thead>
        <tr>
          <th>{{currentPage}} di {{totalItems}} {{watchPage}}</th>
          <th>post_content</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="post in filteredArticoli | filter:searchFilter">
          <td>{{post.title}}</td>
          <td><a ng-href="{{post.featured_image.source}}"><img ng-src="{{post.featured_image.attachment_meta.sizes.thumbnail.url}}"></a></td>
          <td ng-bind-html="post.excerpt"></td>

        </tr>
      </tbody>
    </table>



       <pagination boundary-links="true" 
          max-size="5"
          items-per-page="itemsPerPage"
          total-items="totalItems" 
          ng-model="currentPage" 
          ng-change="pageChanged(page)"></pagination>




</div>
</div>



 </div>
  </body>



</html>

and this is my script.js with angular code (I know it's all in one file and it's bad)

var req = new XMLHttpRequest();
var URL = "/wp-json/posts";
req.open('GET', URL, false);
req.send(null);
var maxpagine = req.getResponseHeader("X-WP-TotalPages");
var totarticoli = req.getResponseHeader("X-WP-Total");
var currentPage = '';
var newPage = '';


  var app = angular.module('applicazioneIndex', ['ui.bootstrap','ngSanitize','ngResource']);

  app.controller('ApplicazioneController', function ($scope, applicazioneFactory) {



applicazioneFactory.get({ id: 1 }, function(data) {
$scope.posts = data;
alert(posts);
});

    $scope.articoli = applicazioneFactory.query();

    $scope.itemsPerPage = 3;
    $scope.currentPage = 1;
    $scope.totalItems = totarticoli;

    $scope.articoli.$promise.then(function () {


    $scope.$watch('currentPage + itemsPerPage', function() {

        var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
        end = begin + $scope.itemsPerPage;
    $scope.filteredArticoli = $scope.articoli.slice(begin, end);

    });

  });

      $scope.$watch('currentPage', function(newPage){
    $scope.watchPage = newPage;
    alert(newPage);

  });  

});


app.factory('applicazioneFactory', function ($resource) {

  return $resource( "/wp-json/posts?page=" + currentPage);

});

Pagination is working perfectly, I get the values from a XMLHttpRequest, the bootstrap menu is populated, but I can't populate content with different JSON.

My goal is to load different JSON files using $currentPage value, changing while bootstrap pagination is working (for that purpose there is an alert to pop up currentPage value).

using $scope.$watch('currentPage', function(newPage) I can get currentPage value inside the controller

I've also a Plunker here http://plnkr.co/edit/hplfuBIOLDHUgUp6lU0A where I've put a static JSON file instead of the dynamic RESTful request url.

How can I put the $currentPage value inside app.factory?

2 Answers 2

0

It will be easier when you load all of your posts and stores them into an $scope variable. And on this variable you can apply an filter. In AngularJS it is possible to create your custom filters.

Lets have a look in module documentation filter.

Example

angular.module('App.filters', []).filter('postFilter', [function () {
    return function (posts, startPost, endPost) {
        if (!angular.isUndefined(posts) && !angular.isUndefined(startPost) && !angular.isUndefined(endPost)) {
            var tempPosts = [];

            for(var i=startPost;i<endPost;i++){
                tempPosts.push(posts[i]);
            }

            return tempPosts;
        } else {
            return posts;
        }
    };
}]);

Normally it should be possible to control the number of given posts via REST-interface.

UPDATE

Okay I believe now what you want. You can add your own resource actions. Something like this:

app.factory('applicazioneFactory', ['$resource', function ($resource) {
    var url = '/wp-json/:action/';
    return $resource(url, {}, {
        getNextPosts: { params: {action: 'posts'}, method: 'GET', isArray: true },
    });
}]);

You can call this method like this:

applicazioneFactory.getNextPosts({'count': 5, 'page': 1, 'post_type': 'Category1'})
applicazioneFactory.getNextPosts({'count': 5, 'page': 1, 'post_type': 'Category2'})
applicazioneFactory.getNextPosts({'count': 5, 'page': 1, 'post_type': 'Category3'})

HTTP-Requests:

http://<yourhost>/wp-json/posts/?count=5&page=1&post_type=Category1 http://<yourhost>/wp-json/posts/?count=5&page=1&post_type=Category2 http://<yourhost>/wp-json/posts/?count=5&page=1&post_type=Category3

More information you will find in the documentation: ngResource

UPDATE 2

You don't need an variable inside your factory and it is no problem to use bootstrap pagination. Please show below I have an function pageChange() inside from your controllers $scope.

var app = angular.module('applicazioneIndex', ['ui.bootstrap','ngSanitize','ngResource']);

app.controller('ApplicazioneController', function ($scope, applicazioneFactory) {

    $scope.itemsPerPage = 3;
    $scope.currentPage = 1;
    $scope.totalItems = 0;

    $scope.pageChange = function(){
      applicazioneFactory.query({'count': $scope.itemsPerPage, 'page': $scope.currentPage}).$promise.then(function(data, status, headers, config){
      $scope.totalItems = headers["X-WP-Total"];
      $scope.filteredArticoli = data;
      });
    }
    // Init on page load
    $scope.pageChange();
});


app.factory('applicazioneFactory',  function ($resource) {
  return $resource('/wp-json/posts');
});

HTML-Snippet

<div class="row">
    <div class="container">  
        <div ng-controller="ApplicazioneController">
            <input type="text" ng-model="searchFilter" class="form-control">
                <table class="table table-hover">
                    <thead>
                        <th>{{currentPage}} di {{totalItems}} {{watchPage}}</th>
                        <th>post_content</th>
                    </thead>
                    <tbody>
                        <tr ng-repeat="post in filteredArticoli | filter:searchFilter">
                            <td>{{post.title}}</td>
                            <td><a ng-href="{{post.featured_image.source}}"><img ng-src="{{post.featured_image.attachment_meta.sizes.thumbnail.url}}"></a></td>
                            <td ng-bind-html="post.excerpt"></td>

                        </tr>
                    </tbody>
                </table>
        </div>
    </div>
</div>

<pagination boundary-links="true" max-size="5" items-per-page="itemsPerPage" total-items="totalItems" ng-model="currentPage" ng-change="pageChange()"></pagination>

Everytime you click on pagination the function pageChange() will be called and send the following HTTP-Requests:

http://<yourhost>/wp-json/posts/?page=1

Hope this will help you

Sign up to request clarification or add additional context in comments.

10 Comments

I think loading all posts data together it should be avoidable because in the case of loading thousands of articles it should take too much loading time: splitting them in smaller json files it's useful. thnks anyway for your quick answer
I agree! My solution is okay for less post. Your REST-Interface should be capable of to control the number of given posts via parameterized HTTP-Requests. So you can load the required posts with click on pagination dynamically. Example for REST-Call: http://<your-host>/wp-json/posts/all?start=1&end=3
Dear Sven Pagination using link is working perfectly. What is not working is to get $currentPage value inside app.factory, it is possible in the controller using $watch and I test it with an alert $scope.$watch('currentPage', function(newPage){ $scope.watchPage = newPage; alert(newPage); but I can't be able to get the same value even if using $watch
I try to make it in a Plunker link
Try this for registration your watcher: $scope.$watch('[currentPage,itemsPerPage]', function () { ... }, true);
|
0

Thanks to this article: How to load json into my angular.js ng-model?

I've found the solutions: Delete the useless app.factory, load all data in controller and rotate the JSON using currentPage change from bootstrap pagination.

This is the working script.js code:

var req = new XMLHttpRequest();
var URL = "/wp-json/posts";
req.open('GET', URL, false);
req.send(null);
var maxpagine = req.getResponseHeader("X-WP-TotalPages");
var totarticoli = req.getResponseHeader("X-WP-Total");
var currentPage = '';
var newPage = '';


var app = angular.module('applicazioneIndex', ['ui.bootstrap','ngSanitize','ngResource']);


app.controller('ApplicazioneController', function($scope, $http) {
    $scope.itemsPerPage = 5;
    $scope.currentPage = 1;
    $scope.totalItems = totarticoli;

$scope.$watch('currentPage', function(newPage){
    $scope.watchPage = newPage;


  $http.get('/wp-json/posts?page=' + newPage)
       .then(function(res){
          $scope.filteredArticoli = res.data; 
$scope.$watch('currentPage + itemsPerPage', function() {

        var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
        end = begin + $scope.itemsPerPage;
    $scope.filteredArticoli = $scope.articoli.slice(begin, end);

      });

    });

  });  

});

Many thanks to Sven Schürmann that helped me in looking for different directions.

Comments

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.