I am self educating myself in angular js. For this i have created a project modelled after an actual project in my job
All get operation work fine but POST is giving me issue
My controller.js
var ngapp = angular.module('ngWebApp', ['angularUtils.directives.dirPagination']);
ngapp.controller('ngIndexController', function ($scope, ngDashboardService) {
$scope.exportData = function (selectedDataList) {
var getData = ngDashboardService.AddReportAudit(selectedDataList)
getData.then(function (result) {
alert(result.data);
}, function () {
alert('Error in getting records');
});
};
});
My service.js
angular.module('ngWebApp').service("ngDashboardService", function ($http) {
this.AddReportAudit = function (dataList) {
var response = $http({
method: "POST",
url: "/Home/AddReportAudit",
data: {
'dataList': JSON.stringify(dataList)
}
});
return response;
};
});
My code of JasonResult in HomeController
public JsonResult AddReportAudit(List<ADTOWebSMARTT_SSOData> dataList)
{
if (dataList != null)
{
using (HRMSystemEntities contextObj = new HRMSystemEntities())
{
var itemList = dataList.Where(x => x.IsChecked == true).ToList();
itemList.ForEach(a => a.DateChecked = DateTime.Now);
contextObj.SaveChanges();
return Json(new { success = true });
}
}
else
{
return Json(new { success = false });
}
}
The problem occurs here
public JsonResult AddReportAudit(List dataList)
For some reason the dataList on reaching AddReportAudit become empty i.e. list has zero element. dataList has 30 records in controller.js and service.js.
I am not sure why that is happening. is there a parsing that I am missing when json data comes from angular to c#
You are actually sending an Object, so the data that reaches your public JsonResult AddReportAudit(....isAnObject), but you are expecting it to be a list. Just change your controller code to the snippet below, it should work.
angular.module('ngWebApp').service("ngDashboardService",
function($http) {
this.AddReportAudit = function (dataList) {
var response = $http({
method: "POST",
url: "/Home/AddReportAudit",
data:JSON.stringify(dataList)
});
return response;
};
});
Solution for angular 1. Place your web service url and change the json data format as per your need. It works.
<!DOCTYPE html>
<html>
<head>
<title>Angular HTTP service</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<table>
<tr>
<th>S No</th>
<th>Source Name</th>
</tr>
<tr ng-repeat="res in result">
<td>{{$index + 1}}</td>
<td>{{res.source_name}}</td>
</tr>
</table>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $http){
$http.get("http://127.0.0.1:4000/all_source").then(function(res){
//console.log(res.data.result);
//console.log(res);
$scope.result = res.data.result;
});
});
</script>
</body>
</html>
Related
I'm trying to intgrate Angular JS with an existing Spring MVC project.
I had à problem calling a Spring controller from the Angular JS controller.
This is my app.js:
'use strict';
var AdminApp = angular.module('AdminApp',[]);
And the service:
'use strict';
AdminApp.factory('AdminService', ['$http', '$q', function($http, $q) {
return {
fetchAllTerminals: function() {
return $http.get('http://localhost:8081/crmCTI/admin/terminal')
.success(function(response) {
console.log('Service');
return response.data;
})
.error(function(errResponse) {
console.error('Error while fetching terminals');
return $q.reject(errResponse);
});
}
};
}]);
and the controller:
'use strict';
AdminApp.controller('AdminController', ['$scope', 'AdminService', function($scope, AdminService) {
var self = this;
self.terminal={id:'',connectedUser:'',type:'',state:''};
self.terminals=[];
self.fetchAllTerminals = function() {
console.log('Controller');
AdminService.fetchAllTerminals()
.success(function() {
self.terminals = d;
})
.error(function() {
console.error('Error while fetching Terminals');
});
};
self.reset = function() {
self.terminal = {id : null, connectedUser : '', type : '', state : ''};
};
}]);
The JSP I'm using to display the data is:
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head></head>
<body ng-app="AdminApp" ng-init="names=['Jani','Hege','Kai']">
<div ng-controller="AdminController as adminController">
<table>
<thead>
<tr>
<th>Id</th>
<th>Login</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="terminal in adminController.terminals">
<td>{{terminal.id}}</td>
<td>{{terminal.connectedUser}}</td>
<td>{{terminal.type}}</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript" src="${pageContext.request.contextPath}/vendors/angular/1.4.4/angular.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/app.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/controller/admin-controller.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/service/admin-service.js"></script>
</body>
</html>
I can access my Spring Controller from a web browser and it returns some data but it's not being called by the Angular JS controller
Am I missing something here?
Could you please help me?
Thank you
To return a data from your service function you should use .then function which has ability to return a data when promise gets resolved OR reject. That you can't to with .success & .error function.
.success & .error method of $http has been **deprecated
Factory
AdminApp.factory('AdminService', ['$http', '$q', function($http, $q) {
return {
fetchAllTerminals: function() {
return $http.get('http://localhost:8081/crmCTI/admin/terminal')
.then(function(response) {
console.log('Service');
return response.data;
},function(errResponse) {
console.error('Error while fetching terminals');
return $q.reject(errResponse);
});
}
};
}]);
Then controller method will again place .then function on the factory method. So the 1st function of .then will get called on resolved of fetchAllTerminals call, if it gets rejected 2nd function will get called.
Controller
self.fetchAllTerminals = function() {
console.log('Controller');
AdminService.fetchAllTerminals()
.then(function(data) {
self.terminals = data;
}, function(error) {
console.error('Error while fetching Terminals');
});
};
try this:
'use strict';
angular.module('AdminApp',[]);
And the service:
'use strict';
angular.module('AdminApp').factory('AdminService', ['$http', '$q', function($http, $q) {
return {
fetchAllTerminals: function() {
return $http.get('http://localhost:8081/crmCTI/admin/terminal')
.success(function(response) {
console.log('Service');
return response.data;
})
.error(function(errResponse) {
console.error('Error while fetching terminals');
return $q.reject(errResponse);
});
}
};
}]);
controller:
'use strict';
angular.module('AdminApp').controller('AdminController', ['$scope', 'AdminService', function($scope, AdminService) {
var self = this;
self.terminal={id:'',connectedUser:'',type:'',state:''};
self.terminals=[];
self.fetchAllTerminals = function() {
console.log('Controller');
AdminService.fetchAllTerminals()
.success(function() {
self.terminals = d;
})
.error(function() {
console.error('Error while fetching Terminals');
});
};
self.reset = function() {
self.terminal = {id : null, connectedUser : '', type : '', state : ''};
};
}]);
I am a novice with Angular. I have a project that a friend and I were working on that acts as a "Reef Tank Controller". It is an arduino/mysql database/angularJS page. My buddy was working on the front end but had to drop out due to work and now I have a semi completed website. From the perspective of the back-end it all works. On the front end I wanted to add a section to control the lighting. I wanted to start out by simply displaying the values of each LED color that is stored in the database. I created a new controller for each LED string I want to display the value of:
'use strict';
/* Controllers */
angular.module('reefController.controllers', ['uiSlider'])
// Main Dashboard Controller
.controller('dashboardController', ['$scope', function($scope) {
$.ajax({
url: 'php/reef_controller_selectVals.php',
type: 'json',
success: function(data) {
reefController.config.data = data;
// Draw Charts
$.each(data.charts, function(name, chartData) {
$(chartData.series).each(function(idx, val){
// Reformat sensor names to their Human readable versions
this.name = reefController.labels[name].sensors[idx];
});
var options = $.extend(reefController.config.chartOptions, {
chart: {
events: {
load: function() {
var chart = this;
setInterval(function() {
$.ajax({
url: 'php/reef_controller_selectVals.php?incremental=' + chart.options.name,
success: function(data) {
// Only add data points if the latest date in the DB is different
if (!(chart.xAxis[0].dataMax == data.timestamp)) {
$(chart.series).each(function(i, series) {
series.addPoint([data.timestamp, data[series.options.id]], true, true);
});
}
}
});
}, reefController.config.timers.chartUpdateInterval);
}
},
renderTo: name
},
name: name,
series: chartData.series,
title: { text: reefController.labels[name].chart.title }
});
var chart = Highcharts.StockChart(options);
reefController.config.charts[name] = chart;
});
//Set LED Value Labels
// Set outlets
var i = 0;
$('.outlet').each(function(){
if (!$(this).hasClass('constant')) {
$(this).attr('data-outlet-id', data.outlets[i].id)
.attr('data-reveal-id', 'date-time-modal')
.attr('data-on-time', data.outlets[i].on_time)
.attr('data-off-time', data.outlets[i].off_time);
if (data.outlets[i].active) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
i++;
// Bind click event to outlets
$(this).click(function(){
var outlet = $(this);
var id = outlet.attr('data-outlet-id');
var newOutletState = (outlet.hasClass('active')) ? 0 : 1;
// Set datepickers to currently defined DB times
$('#on_time').val(outlet.attr('data-on-time'));
$('#off_time').val(outlet.attr('data-off-time'));
// Formatter function for date time pickers
var dateFormatter = function(elem, current_time) {
elem.html(moment(current_time).format('ddd M/D/YY HH:mm'));
};
$('#on_time').datetimepicker({
format: 'Y-d-m H:i:s',
inline: true,
defaultDate: outlet.attr('data-on-time'),
onChangeDateTime: function(current_time) { dateFormatter($('#on_time_display'), current_time) },
onGenerate: function(current_time) { dateFormatter($('#on_time_display'), current_time) }
});
$('#off_time').datetimepicker({
format: 'Y-d-m H:i:s',
inline: true,
defaultDate: outlet.attr('data-off-time'),
onChangeDateTime: function(current_time) { dateFormatter($('#off_time_display'), current_time) },
onGenerate: function(current_time) { dateFormatter($('#off_time_display'), current_time) }
});
// Submit Button
$('#submit-btn').click(function() {
data = {
'id': id,
'on_time': $('#on_time').val(),
'off_time': $('#off_time').val(),
'active': newOutletState
};
$.ajax("php/reef_controller_loadOutlet.php", {
type: 'POST',
data: data,
dataType: 'json',
success: function(data) {
outlet.toggleClass('active');
}
});
$('#date-time-modal').foundation('reveal', 'close');
});
// Cancel Button
$('#cancel-btn').click(function(){
$('#date-time-modal').foundation('reveal', 'close');
});
});
}
});
}
});
}])
.controller('outletController', ['$scope', function($scope) {
$.ajax({
url: 'img/outlet.svg',
success: function(svg) {
var svgDoc = document.importNode(svg.documentElement, true);
$('.outlet').append(svgDoc);
}
});
}])
.controller('temperatureController', ['$scope', function($scope) { }])
.controller('phController', ['$scope', function($scope) { }])
.controller('whiteLedCtrl', ['$scope', function($scope) {}])
.controller('blueLedCtrl', ['$scope', function($scope) {}])
.controller('variousColorLedCtrl', ['$scope', function($scope) {}]);
In my dashboard.html file I have:
<table style="width: 100%;">
<tr>
<td>
{{ ledValues }}
</td>
</tr>
<tr>
<td colspan="3" style="background: #eff4f6;"><input type="checkbox" name="overrideLightingSchema" value="overRide">
Override Current Lighting Pattern
</td>
</tr>
<tr>
<td colspan="3">
<select name="lightingSchemas">
<option value="feedingLightingPattern">Feeding Schema</option>
<option value="morningLightingPattern">Morning Schema</option>
<option value="standardLightingPattern">Standard Schema</option>
<option value="twilightLightingPattern">Dusk Schema</option>
<option value="nightTimeLightingPattern">Night Schema</option>
<option value="deepNightLightingPattern">Late Night Schema</option>
</select>
</td>
</tr>
</table>
Sometimes this displays the values from the database other times it just says:
{{ ledValues }}
It may be an async issue of some sort but my angular, well JS for that matter, is weak. Any help would be great.
The main issue I can see here is that you are using $ajax to make requests to the server.
You use the response from the server to set your variable...
reefController.config.data = data;
However since $ajax is not part of Angular this update occurs outside of the scope digest. Therefore Angular does not know to update the binding. You could try wrapping you assignment in $apply.
$scope.$apply(function(){
reefController.config.data = data;
});
That said, I cannot see where reefController is defined. You probably want to be assigning it to the scope:
$scope.$apply(function(){
$scope.MyData = data;
});
However, I would actually recommend you replace the $ajax calls with the Angular $http service.
//inject $http
.controller('dashboardController', ['$scope', '$http', function($scope, $http) {
//then use it later on
$http({
method: 'GET',
url: 'php/reef_controller_selectVals.php'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
$scope.MyData = data;
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Example
Below Is a very quick example of how to use $http to get the data from the server.
The full example, including a fake service (that does not require a server response) can be found here: http://codepen.io/anon/pen/GogWMV
'use strict';
angular.module('reefApp', [ 'uiSlider']);
/* CONTROLLER */
angular.module('reefApp')
.controller('dashboardController', dashboardController);
/* Define controller dependencies.
Note how we do not use $scope as we are using controller as vm syntax
And we assign our scope variables to 'ctrl' rather than scope directly.
see john papa styleguide (https://github.com/johnpapa/angular-styleguide#style-y032)
*/
dashboardController.$inject = ['ledService'];
function dashboardController(ledService)
{
var ctrl = this;
//define an array to hold our led data
ctrl.ledData = [];
//call method to get the data
getLedData();
//this method uses our service to get data from the server
//when the response is received it assigns it to our variable
//this will in turn update the data on screen
function getLedData()
{
ledService.getLedData()
.then(function(response){
ctrl.ledData = response.data;
});
}
}
/* LED SERVICE */
/* the service is responsible for calling the server to get the data.
*/
angular.module('reefApp')
.factory('ledService', ledService);
ledService.$inject = ['$http'];
function ledService($http)
{
var endpointUrl = "http://addressOfYourEndpoint";
/* expose our API */
var service = {
getLedData: getLedData,
}
return service;
function getLedData()
{
/* this is how you would call the server to get your data using $http */
/* this will return a promise to the calling method (in the controller)
when the server returns data this will 'resolve' and you will have access to the data
in the controller:
Promises: http://andyshora.com/promises-angularjs-explained-as-cartoon.html*/
return $http.get(endpointUrl);
}
}
Taking this further, best practice would be to hold a reference to the data returned from the server inside the service; one reason is the service is a singleton - so this data service and it's data can be shared across controllers.
function ledService($http)
{
var endpointUrl = "http://addressOfYourEndpoint";
/* expose our API */
var service = {
ledData: [],
getLedData: getLedData,
}
return service;
function getLedData()
{
return $http.get(endpointUrl)
.then(function(response)
{
/* assign response to service variable, before promise is returned to caller */
service.ledData = response.data;
});
}
}
Then in our controller...
function getLedData()
{
ledService.getLedData()
.then(function(response){
ctrl.ledData = ledService.ledData;
});
}
Update
To collect more data, you could add a service for each piece of data you want to collect - or add more methods to existing service. Let's assume you add a phService.
You then inject this into your controller. And add call a new method to use the service to the data and assign to the model. It can then be shown in the view.
dashboardController.$inject = ['ledService', 'phService'];
function dashboardController(ledService, phService)
{
var ctrl = this;
//our data will be stored here
ctrl.ledData = [];
ctrl.phData = [];
//call methods to get the data
getLedData();
getPhData();
function getLedData()
{
ledService.getLedData()
.then(function(response){
ctrl.ledData = response.data;
});
}
function getPhData()
{
phService.getPhData()
.then(function(response){
ctrl.phData = response.data;
});
}
}
Then in the view (HTML):
<tr ng-repeat="ph in ctrl.phData">
<td> PHValue</td>
<td >
{{ ph }}
</td>
</tr>
I am trying to consume Web API using AngularJs but getting struck angular side which is hard for me to figure out.
I created HTML, controller and service. Everything seems ok to me but when running the app i get the injection error.
html
<html >
<head>
<title>Motors </title>
<script src="/Scripts/angular.js"></script>
<script src="/Scripts/angular-route.js"></script>
<script src="/View/motorController.js"></script>
</head>
<body ng-app="myApp" ng-controller="motorController">
<div>
<table class="table">
<tr>
<th>Id</th>
<th>Name</th>
<th>Country</th>
</tr>
<tr ng-repeat="m in motors">
<td>{{m.Id}}</td>
<td>{{m.Name}}</td>
<td>{{m.Country}}</td>
</tr>
</table>
</div>
</body>
</html>
AngularJs controller
var module = angular.module('myApp', [])
.controller('motorController', ['$scope', '$motorService',function ($scope, motorService) {
getMotors();
function getMotors() {
motorService.GetAllMotors()
.success(function (motors) {
$scope.motors = motors;
})
.error(function (error) {
$scope.status = 'Unable to load motor data: ' + error.message;
});
}
}]);
angular service
motorApp.factory('motorService', function ($http) {
var urlBase = 'http://localhost:40738/api';
var motorService = {};
motorService.GetAllMotors = function () {
return $http.get(urlBase + '/GetAllMotors');
};
return motorService;
});
Error i am getting on chrmoe browser console
Error: [$injector:unpr] Unknown provider: $motorServiceProvider <- $motorService <- motorController
You have a extra $ infront of MotorService, change
From:
.controller('motorController', ['$scope', '$motorService',function ($scope, motorService)
To:
.controller('motorController', ['$scope', 'motorService',function ($scope, motorService)
The problem with your code is that the factory is given a different module name "motorApp" instead of module name "module".
Use
module.factory('motorService', function ($http) { //change here
var urlBase = 'http://localhost:40738/api';
var motorService = {};
motorService.GetAllMotors = function () {
return $http.get(urlBase + '/GetAllMotors');
};
return motorService;
});
Also in your controller you should remove the "$" from injected service name "motorService"
var module = angular.module('myApp', [])
.controller('motorController', ['$scope', 'motorService',function ($scope, motorService) {
getMotors();
function getMotors() {
motorService.GetAllMotors()
.success(function (motors) {
$scope.motors = motors;
})
.error(function (error) {
$scope.status = 'Unable to load motor data: ' + error.message;
});
}
}]);
I have implemented code to retrieve data from MVC Controller using Angular-JS using ngRoute. What I have implemented is, I have two action methods in MVC controller and at client side I have two menu buttons and by clicking on each button, it retrieves data from respective action method. I have used Angular-Route, Angular Factory Method and ng-view
Till now it is fine. But what I can see is AngularJS doesn't go to Action Method every time when i click on the button. Once data have been retrieved, it only shows the respective view. And in this situation I cannot retrieve fresh data from database. So If I have to call action method every time how can I achieve this ?
This is what I have implemented:
AccountController:
public ActionResult GetAccounts()
{
var repo = new AccountRepository();
var accounts = repo.GetAccounts();
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var jsonResult = new ContentResult
{
Content = JsonConvert.SerializeObject(accounts, settings),
ContentType = "application/json"
};
return jsonResult;
}
public ActionResult GetNumbers()
{
var repo = new AccountRepository();
var numbers = repo.GetNumbers();
var setting = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var jsonResult = new ContentResult()
{
Content = JsonConvert.SerializeObject(numbers, setting),
ContentType = "application/json"
};
return jsonResult;
}
Account.JS:
'use strict';
var account = angular.module('accountModule', ['ngRoute']);
account.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/Employees', { templateUrl: '../Templates/Employees.html', controller: 'accountController' })
.when('/Numbers', { templateUrl: '../Templates/Numbers.html', controller: 'numberController' })
.otherwise({
redirectTo: '/phones'
});;
}]);
account.controller('accountController', [
'$scope',
'accountService',
function ($scope, accountService) {
accountService.getEmployees().then(function(talks) {
$scope.employees = talks;
}, function() {
alert('Some error');
});
}
]);
account.controller('numberController', [
'$scope',
'accountService',
function ($scope, accountService) {
accountService.getNumbers().then(function (retrievedNumbers) {
$scope.telephoneNumbers = retrievedNumbers;
}, function () {
alert('error while retrieving numbers');
});
}
]);
AccountService.JS:
account.factory('accountService', ['$http', '$q', function ($http, $q) {
var factory = {};
factory.getEmployees = function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'GetAccounts'
}).success(deferred.resolve).error(deferred.reject);
return deferred.promise;
};
factory.getNumbers = function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'GetNumbers'
}).success(deferred.resolve).error(deferred.reject);
return deferred.promise;
};
return factory;
}]);
and my view is something like this:
#{
ViewBag.Title = "Index";
Layout = "~/Views/shared/_Layout.cshtml";
}
<script type="text/javascript" src="../../Scripts/Modules/Account/Account.js"></script>
<script type="text/javascript" src="../../Scripts/Modules/Account/AccountService.js"></script>
<div ng-app="accountModule">
<div>
<div class="container">
<div class="navbar navbar-default">
<div class="navbar-header">
<ul class="nav navbar-nav">
<li class="navbar-brand">Employees</li>
<li class="navbar-brand">Numbers</li>
</ul>
</div>
</div>
<div ng-view>
</div>
</div>
</div>
</div>
I am trying a quick test to debug why some of my code isn't working as expected.
I have a controller named testCtrl and a service myService . In the service, I am trying to get data from Parse and once I have the data, I am trying to load this data into my frontend html.
Here's the code:
app.controller('testCtrl', function($scope,myService) {
var currentUser = Parse.User.current();
$scope.username = currentUser.getUsername();
$scope.test = "ths";
var promise1 = myService.getEvaluatorData();
promise1.then(function(response){
$scope.results2 = response;
console.log(response);
});
});
app.factory('myService', function(){
return {
getAllData: function($scope){
getEvaluatorData($scope);
},
getEvaluatorData: function(){
var evaluators = Parse.Object.extend("Evaluators");
query = new Parse.Query(evaluators);
return query.find({
success: function(results){
angular.forEach(results, function(res){
console.log("Looped"); //this is just to verify that the then call below is executed only after all array objects are looped over.
});
} ,
error: function(error){
}
});
}
}
});
Here's the html code where I want to display the data:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-controller="testCtrl">
{{test}}
{{results2}}
</body>
</html>
The results2 don't load up in the html.
Here is the console log.
testParse.js:46 This is done
2015-07-10 15:28:32.539testParse.js:46 This is done
2015-07-10 15:28:32.540testParse.js:46 This is done
2015-07-10 15:28:32.541testParse.js:46 This is done
2015-07-10 15:28:32.542testParse.js:56 Returning result as promised [object Object],[object Object],[object Object],[object Object]
You need to return data from your service and pass it to your controller. For ex:
app.controller('testCtrl', function ($scope, myService) {
var currentUser = Parse.User.current();
$scope.username = currentUser.getUsername();
$scope.test = "this";
myService.getEvaluatorData().then(function (response) {
console.log('response', response);
$scope.results2 = response;
});
});
app.factory('myService', function ($http, $q) {
return {
getEvaluatorData: function () {
var evaluators = Parse.Object.extend("Evaluators");
var query = new Parse.Query(evaluators);
return query.find({
success: function (results) {
return results;
},
error: function (error) {
return error;
}
});
}
}
});
Also, no point in calling this.getEvaluatorData($scope) in my opinion, when you can call the getEvaluatorData method directly
use $rootScope.result2 instead of $scope.result2