I am trying to implement the Bootstrap UI Angular Carousel with WordPress WP-API. I am curious how to connect 'slides' with 'posts'
The demo HTML is...
<div class="carousel" ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
</div>
</div>
The javascript works fine separately. For example, I can use ng-repeat to display posts. The sample ng-repeat="slide in slides" displays the demo slides.
angular.module('app', ['ngRoute', 'ui.bootstrap' ])
// Retrieves Posts
.controller('Main', function($scope, $http, $routeParams){
$http.get('wp-json/posts/').success(function(res){
$scope.posts = res;
});
$http.get('wp-json/media/').success(function(res){
$scope.media = res;
});
})
The example Bootstrap implementation is...
//Bootstrap Carousel
.controller('CarouselDemoCtrl', function ($scope) {
$scope.myInterval = 5000;
var slides = $scope.slides = [];
$scope.addSlide = function() {
var newWidth = 600 + slides.length + 1;
slides.push({
image: 'http://placekitten.com/' + newWidth + '/300',
text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' ' +
['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
});
};
});
How would I implement something that connects the slides and the posts? That way, it grabs, for example, the featured image from a post and inserts it into a slide?
I'm not a WP guy at all, but my approach here would be to loop through the results you're getting in the "Retrieve Posts" controller and reformat into simple JSON objects that your Slideshow will use. Eg:
angular.forEach($scope.posts, function(val, idx)
{
var newObj = { body: val.postBody, ect: val.postEtc };
$scope.slides.push(newObj);
});
Same applies for the Media results; loop through them and align with your custom objects. If you want to access them more easily, you can use array notation instead of .push() to make accessing the objects from each loop really fast assuming you have an ID or something that's simple to work with, eg:
$scope.slides[val.postID] = { body: val.postBody, etc: val.postEtc };
This means that now when you loop through the Media results you can use the same loop structure as Posts, but modify it so you set the object property you need:
// While looping through media objects, assuming the media object has a postID
$scope.slides[media.postID].image = mediaObj.imageUrl;
And so on.
There is a caveat here... you want to make sure you have the posts -and- media before you attempt to loop through them. Your current controller will make both AJAX calls as soon as the controller is instantiated (when angular compiles the ng-controller directive on your view). These 2 calls will happen asynchronously so the order of completion is unknown; you can't rely on a timeout, you'll have to chain the requests using q.defer(). You'll need to re-write the controller a bit, inject $q in the constructor, and chain the promises:
// store the app in a variable so you can write more modules / directives with it
var app = angular.module('app', ['ngRoute', 'ui.bootstrap' ])
// Retrieves Posts
app.controller('Main', function($scope, $http, $routeParams, $q){
// create a deferred object
var def = $q.defer();
var promises = []; // Array of promises for our deferred wrapper
// All HTTP requests return a promise object; push it on to our array
promises.push($http.get('wp-json/posts/').success(function(res){
$scope.posts = res;
}));
// Push the 2nd promise
promises.push($http.get('wp-json/media/').success(function(res){
$scope.media = res;
}));
// Process when all are complete
def.all(promises).then(function(res)
{ // Successful (promise resolved)
// Loop through the results in $scope.posts / $scope.media, build your objects
}, function(res)
{ // Failed (promise rejected)
// Do something here if a promise is rejected
});
});
Your UI Carousel should update as your slides array changes!