I am trying to create an app that counts likes for beer! This would updates the API the beers are stored on and in turn update the number of likes on the API and angularJS view using the PUT method. I am able to get the view to work correctly increasing every time the like is clicked. I am unsure why my PUT method continues to return a 404 and will not update the API. please see code below for my put method. I have also included my JS and HTML for this. I feel like I am close but cannot figure out how to get the "likes" to update on the API. Thank you in advance!! I think i am passing incorrect data to the PUT method.
HTML:
<div ng-app="beerApp" ng-controller="BeerController" class="jumbotron">
<div class="all-beer">
<div class="single-beer" ng-repeat="beer in allBeer">
<div>{{beer.name}}</div>
<div>{{beer.likes}}</div>
<button ng-click="decrease(beer)">X</button>
<button ng-click="increase(beer)">\3</button>
</div>
</div>
</div>
JS:
angular.module('beerApp', []).controller('BeerController', function($scope, $http) {
$scope.allBeer = [];
$scope.beerSum = function() {
$http({
method: 'GET',
url: /api/beers
}).
then( function(response) {
if(typeof response === 'object') {
var dataArr = response.data;
for (var i = 0; i < dataArr.length; i++) {
var beer = dataArr[i];
$scope.allBeer.push(beer);
}
} else {
return;
}
}, function(error) {
console.log('i am an error', error);
})
};
$scope.beerSum();
$scope.increase = function(beer){
var newLikes = beer.likes++;
$http({
method: 'PUT',
url: '/api/beer/',
data: JSON.stringify($scope.allBeer.likes),
}).then(function successCallback(response) {
console.log("Updated!");
}, function errorCallback(response) {
console.log("not updated")
});
};
First things first you are missing some syntax for the http api's. Secondly you are calling a property on an array that doesn't exist. Thirdly your api won't work because of the logic that you have. You have an array of beers and you want to increase the likes on a single beer. Create a method on the server that accepts a beer, the server will take that beer and increase it's likes by 1, then save to the database or whatever.
Depending on the server you are using you have two options.
You can define a command simply at /api/beers
and configure the server to accept an object and use that objects id for the server update. If this is the case I recommend creating this endpoint, /api/beers/update
and make it a POST, and pass it the object, then within this command do all your update logic.
Or for example the Microsoft Web Api the default put (update) endpoint looks like so, public void Update(int id, object data){}
with a url of /api/beers/{id}
. To use this method you need to change the code for the updateLikes
method I wrote.
See Below:
$scope.updateLikes = function(beer, likeCount){
beer.likes+= likeCount;
$http({
method: 'PUT',
url: '/api/beer/' + beer.id,
data: JSON.stringify(beer),
}).then(function successCallback(response) {
console.log("Updated!");
//Trigger reload of data
$scope.beerSum();
}, function errorCallback(response) {
console.log("not updated")
});
};
If you are still having trouble and are working in a GitHub environment I would gladly help you with your code more directly. Other than that the answer I have posted answer's your question, and does so in what I believe to be good coding practices for AngularJS. With one minor exception there code be a changes to the line that reads, beer.likes += likeCount
because this also updates the original beer object. I suppose that is preference, but please contact me if you need more help.
angular.module('beerApp', []).controller('BeerController', function($scope, $http) {
$scope.allBeer = [];
$scope.beerSum = function() {
$http({
method: 'GET',
url: '/api/beers' //<-- Added string opening and closing tags
}).
then( function(response) {
if(typeof response === 'object') {
var dataArr = response.data;
for (var i = 0; i < dataArr.length; i++) {
var beer = dataArr[i];
$scope.allBeer.push(beer);
}
} else {
return;
}
}, function(error) {
console.log('i am an error', error);
})
};
$scope.beerSum();
$scope.increase = function(beer){
var newLikes = beer.likes++;
//Your code
$http({
method: 'PUT',
url: '/api/beer/', //<-- closing
data: JSON.stringify($scope.allBeer.likes), //<-- Where does likes come from? $scope.allBeer is an array of beer but the array itself doesn't have a property called likes.
}).then(function successCallback(response) {
console.log("Updated!");
}, function errorCallback(response) {
console.log("not updated")
});
//End your code
//My Code
beer.likes+=1; //<-- My bad I fixed this.
$http({
method: 'PUT',
url: '/api/beer/', //<-- closing
data: JSON.stringify(beer), //<-- The object you passed into the function
}).then(function successCallback(response) {
console.log("Updated!");
}, function errorCallback(response) {
console.log("not updated")
});
//End my code
};
angular.module('beerApp', []).controller('BeerController', function($scope, $http) {
$scope.allBeer = [];
$scope.beerSum = function() {
$scope.allBeer.push({
"name": "Miller Lite",
"likes": 0
});
$http({
method: 'GET',
url: '/api/beers' //<-- Added string opening and closing tags
}).
then( function(response) {
if(typeof response === 'object') {
var dataArr = response.data;
for (var i = 0; i < dataArr.length; i++) {
var beer = dataArr[i];
$scope.allBeer.push(beer);
}
}
}, function(error) {
console.log('i am an error', error);
})
};
$scope.beerSum();
$scope.updateLikes = function(beer, likeCount){
beer.likes+= likeCount;
$http({
method: 'PUT',
url: '/api/beer/',
data: JSON.stringify(beer),
}).then(function successCallback(response) {
console.log("Updated!");
//Trigger reload of data
$scope.beerSum();
}, function errorCallback(response) {
console.log("not updated")
});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<script data-require="[email protected]" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-app="beerApp" ng-controller="BeerController" class="jumbotron">
<h1>Beers on Tap</h1>
<div class="all-beer">
<div class="single-beer" ng-repeat="beer in allBeer">
<div>{{beer.name}}</div>
<div>{{beer.likes}}</div>
<button ng-click="updateLikes(beer, -1)">Down Vote</button>
<button ng-click="updateLikes(beer, 1)">Up Vote</button>
</div>
</div>
</div>
</body>
</html>