Reputation: 995
I know there are a lot of similar questions to this - I'm new to AngularJS and struggling with data binding. I've done some simple examples with local models and controllers but am now trying to expand to using a REST service and splitting out services from the controller. I feel like I should be updating my model $forecastData variable at the end of the create so this gets bound back to the screen, but I can't access from the service. The data is created successfully from the post and if I refresh the browser the data appears correctly - I just want this screen update to happen automatically as it should.
My screen is like this:
<!DOCTYPE html>
<html ng-app="MeterApp">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.js"></script>
<script src="https://rawgit.com/krispo/angular-nvd3/v1.0.4/dist/angular-nvd3.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body class="container">
<div class="panel panel-primary" ng-controller="ForecastFormController" ng-init="getData()">
<div class="panel-heading">Forecast Data</div>
<div class="panel-body">
<table class="table table-bordered table-hover">
<tr>
<th>Forecast Date</th>
<th>Value (kWh)</th>
<tr ng-repeat="forecast in forecastData"">
<td>{{forecast.forecast_date}}</td>
<td>{{forecast.value_kwh}}</td>
</tr>
</table>
</div>
</div>
<div class="panel panel-primary col-lg-4" ng-controller="ForecastFormController">
<div class="panel-heading">Add Forecast</div>
<div class="panel-body">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="forecast-date">Forecast Date:</label>
<input class="form-control" id="forecast-date" ng-model="forecast.forecast_date">
<br>
<label for="forecast-value">Forecast Value (KwH):</label>
<input class="form-control" id="forecast-value" ng-model="forecast.value_kwh">
<br>
<button type="submit" class="btn btn-default" ng-click="create()">Submit</button>
</div>
</form>
</div>
</div>
</body>
</html>
Services/controller are:
app.service('forecastDataService', function($http) {
this.getData = function() {
return $http({
method: 'GET',
url: 'http://localhost:51437/api/forecasts'
});
}
this.addData = function(f){
return $http({
method: 'POST',
url: 'http://localhost:51437/api/forecasts',
});
}
});
app.controller('ForecastFormController', function($scope, forecastDataService) {
/* $scope.forecastData = [ {"id":1,"value_kwh":1000.0,"forecast_date":"2015-11-27T00:00:00"},{"id":2,"value_kwh":1000.0,"forecast_date":"2015-11-28T00:00:00"},{"id":4,"value_kwh":1000.0,"forecast_date":"2015-11-29T00:00:00"}]; */
$scope.forecastData = null;
$scope.foreast = {};
$scope.getData = function(){
forecastDataService.getData().then(function(dataResponse) {
$scope.forecastData = dataResponse.data;
console.dir($scope.forecastData);
return $scope.forecastData;
});
}
$scope.create = function(){
console.dir("Called create method with: " + $scope.forecast.value_kwh + ":" + $scope.forecast.forecast_date);
forecastDataService.addData($scope.forecast).then(function(dataResponse) {
console.dir("Success - data response: " + dataResponse.data);
});
}
})
Upvotes: 0
Views: 1219
Reputation: 995
Thanks very much for the above answer. After looking at the angular js up and running book the obvious (most simple way seemed to be to refactor as follows):
Service:
app.service('forecastService', ['$http', function($http) {
return{
get: function(){
return $http.get('http://localhost:51437/api/forecasts');
},
create: function(data){
return $http.post('http://localhost:51437/api/forecasts', data)
}
};
}]);
Controller:
app.controller('ForecastController', ['forecastService', function(forecastService) {
/* $scope.forecastData = [ {"id":1,"value_kwh":1000.0,"forecast_date":"2015-11-27T00:00:00"},{"id":2,"value_kwh":1000.0,"forecast_date":"2015-11-28T00:00:00"},{"id":4,"value_kwh":1000.0,"forecast_date":"2015-11-29T00:00:00"}]; */
var self = this
self.forecastData = [];
self.newForecast = {};
var getData = function(){
return forecastService.get().then(
function(response){
self.forecastData = response.data;
}, function(errResponse){
console.error('Error while fetching data: ');
console.error(errResponse);
});
};
getData();
self.create = function(){
forecastService.create(self.newForecast)
.then(getData)
.then(function(response){
self.newForecast = {};
});
};
}]);
Upvotes: 0
Reputation: 61
You can return a object from service and when you want to refresh data, simply call refresh function like:
app.service('forecastDataService', function($http) {
var data = {
forecast: {}
};
this.getData = function() {
return data;
}
this.refreshData = function(f){
$http({
method: 'POST',
url: 'http://localhost:51437/api/forecasts',
}).then(unction(dataResponse) {
data.forecast = dataResponse.data;
});
}
});
Use the service in controller:
$scope.forecastData = forecastDataService.getData();
Getting newest data from server and update to view
forecastDataService.refreshData();
Upvotes: 1