My Grails application doesn't receiving data from angularjs post request.
My AngularJS Controller is:
module.controller('MemberCtrl', ['$scope', '$http',
function ($scope, $http) {
$scope.submitForm = function () {
$http.post(uri + "receiveNewMember", $scope.member)
.success(function (data) {
console.log("Data Sent With Success! " + data);
})
.error(function (data) {
console.log("Fail");
});
};
}]);
My Grails Action is:
def receiveNewMember(){
render text: params.name
}
The Debugger Stops into action. But params variable hasn't any data but controller and action.
Someone knows how can I fix this?
The Post Data can be accessed via request.JSON in Grails Controller.
You can do something like this to emulate the way grails works:
post query parameters like jQuery
Also I created a Serializer factory to serialize any kind of javascript object to the expected way on grails:
(function() {
'use strict';
angular.module('app').factory('Serializer', function ($filter) {
function SerializerService(){}
var serializerService = new SerializerService();
serializerService.excludedProperties = ['$$hashKey'];
SerializerService.prototype.serialize = function(object){
var results = {};
this.serializeObject(results, object, "");
return results;
};
SerializerService.prototype.serializeObject = function(results, object, nameAtTheMoment){
if($.isArray(object)){
var array = object;
for (var i=0; i<object.length; i++){
var newNameAtTheMoment = nameAtTheMoment + "[" + i.toString() + "]";
this.serializeObject(results, array[i], newNameAtTheMoment)
}
}
else{
if(Object.prototype.toString.call( object ) === "[object Object]"){
var i=0;
for(var property in object){
if (object.hasOwnProperty(property) && this.excludedProperties.indexOf(property) == -1) {
var newNameAtTheMoment;
if(nameAtTheMoment !== "")
newNameAtTheMoment = nameAtTheMoment + "." + property;
else
newNameAtTheMoment = property;
this.serializeObject(results, object[property], newNameAtTheMoment);
i++;
}
}
}
else{ //the object is a simple value
if(Object.prototype.toString.call(object) === '[object Date]'){
var dateServerFormat = window.appConfig.dateServerFormat;
results[nameAtTheMoment] = $filter('date')(object, dateServerFormat);
}
else
results[nameAtTheMoment] = object;
}
}
};
return serializerService;
});
})();
And following the first link description you can do something like this:
angular.module('app', [...])
.config(function ($provide, $httpProvider) {
var serializer;
// Trick to inject dependencies on the config function.
$provide.factory('FactoryInjector', function () {
return {
setSerializer: function(serializerParam){
serializer = serializerParam;
}
};
});
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
$httpProvider.defaults.transformRequest = [function(data) {
return angular.isObject(data) && String(data) !== '[object File]' ? $.param(serializer.serialize(data)) : data;
}];
})
.run(function ($rootScope, $state, $stateParams, Serializer, FactoryInjector) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
FactoryInjector.setSerializer(Serializer);
});
Related
I am very new to AngularJS.
I want to pass an array data from my app factory to app controller.
Here is my app.factory code.
App.factory('buyFactory', ['$http', function($http) {
factory.Search = function(scope, d) {
var data = scope.search;
scope.CarsData = [];
all_cars = [];
scope.isLoading = true;
$http.post(ajaxurl + '?action=search_car', d)
.success(function(response) {
angular.forEach(response, function(c) {
c.price = parseFloat(c.price);
c.driven = parseFloat(c.driven);
c.year = parseFloat(c.year);
});
angular.forEach(response, function(value, key) {
all_cars.push(value);
scope.CarsData = all_cars;
scope.TotalItems = scope.CarsData.length;
scope.isLoading = false;
})
.error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
scope.isLoading = false;
});
}
return factory;
}]);
and this is app.controller as
App.controller('buyController', ['$scope', '$http', 'buyFactory', '$filter', function($scope, $http, buyFactory, $filter) {
$scope.CarsScroll = buyFactory.Search.CarsData();
$scope.loadMore = function() {
var last = $scope.CarsScroll[$scope.CarsScroll.length - 1];
for (var i = 1; i <= 3; i++) {
$scope.CarsScroll.push(last + i);
}
};
//scroll
}]);
I want to use output obtained from factory i.e. CarsData as a variable in my app controller. But I am not able to get it. I have tried using services also. Is there method to use array data in a simplest way.
Your syntax is completely broken, i would recommend following any course of AngularJS. As for how to correctly do what you are trying to would look something like this
app.factory('buyFactory', ['$http', '$q', function($http, $q) {
var factory = {
search: function(d) {
return $q(function(resolve, reject) {
$http.post(ajaxurl + '?action=search_car', d).then(function(response) {
angular.forEach(response, function(c) {
c.price = parseFloat(c.price);
c.driven = parseFloat(c.driven);
c.year = parseFloat(c.year);
});
var carsData = [];
angular.forEach(response, function(value, key) {
carsData.push(value);
})
var result = {
carsData: carsData,
total: carsData.length
}
resolve(result);
}, function(error) {
reject(error);
})
});
}
}
return factory;
}]);
app.controller('buyController', ['$scope', '$http', 'buyFactory', '$filter', function($scope, $http, buyFactory, $filter) {
buyFactory.search().then(function(result) {
var cars = result.carsData;
var total = result.total;
})
}]);
Note: i do not know what the d parameter is for neither why the angular.forEach statements so it might not be fully functional. But this is more as guideline for how your factory should look and be used.
I'm using a controller to call a service that will make an $http request, but right now I've only set my service to return a string because I want to make sure it works and is calling properly.
When I run it, I get the following error:
TypeError: monitorData.requestEvent(...).success is not a function
My code below:
Controller
(function() {
angular
.module('monitorApp')
.controller('eventCtrl', eventCtrl);
eventCtrl.$inject = ['$scope', '$routeParams', 'monitorData'];
function eventCtrl($scope, $routeParams, monitorData) {
var vm = this;
vm.eventid = $routeParams.eventid;
vm.event = {};
vm.getData = function(eventid) {
console.log("getData variable accessed");
monitorData.requestEvent(eventid)
.success(function(data) {
console.log(data);
})
.error(function(e) {
console.log("Error");
});
return false;
};
vm.getData(vm.eventid);
}
})();
Service
(function() {
angular
.module('monitorApp')
.service('monitorData', monitorData);
monitorData.$inject = ['$http'];
function monitorData($http) {
var requestEvent = function(eventid) {
var gas = "Event " + eventid + " requested.."
console.log(gas);
return gas;
};
return {
requestEvent : requestEvent,
};
}
})();
In order to be chained, it should return a settled promise.
monitorData.$inject = ['$http', '$q'];
function monitorData($http, $q) {
var requestEvent = function(eventid) {
var gas = "Event " + eventid + " requested.."
console.log(gas);
return $q.resolve(gas);
};
return {
requestEvent : requestEvent,
};
}
And by the way, success and error are deprecated legacy methods. It is always then and catch now.
success and error are part of the promise and you are not returning promise.
To make it work,you should use defer which resolve to success
and return promise which later chained with .success and .error
monitorData.$inject = ['$http','$q'];
var defer = $q.defer();
function monitorData($http) {
var requestEvent = function(eventid) {
var gas = "Event " + eventid + " requested.."
defer.resolve(gas)
return defer.promise;
};
return {
requestEvent : requestEvent,
};
}
This is the service, it use $q and promise to wait for http.jsonp return the data.
var app=angular.module('myModule', ['ngSanitize']);
app.service('httpq', function ($http, $q)
{
return {
get: function(url)
{
var defferer = $q.defer()
$http.jsonp(url).success(function (data){
defferer.resolve(data)
})
return defferer.promise
}
}
});
This is the controller, it split comment text at first and use forEach & http calls to find the userid of #username from remote server, then add href like [a href="#/app/userid]#username[/a]
app.controller('HelloCtrl', function($scope, httpq, $http)
{
var items=[];
var url = 'https://api.instagram.com/v1/media/1059951115357899614_375673057?access_token=242292692.1fb234f.bbbbfc4972fb4bdea524e5c382cd7e48&callback=JSON_CALLBACK';
httpq.get(url).then(function (data) {
angular.forEach(data.data.comments.data, function(value, key) {
var tagslistarr = value.text.split(' ');
var text='';
angular.forEach(tagslistarr, function(value2, key2) {
if(value2.indexOf('#') == 0){
username = value2.substring(1);
var url2='https://api.instagram.com/v1/users/search?q='+username+'&count=1&access_token=242292692.1fb234f.bbbbfc4972fb4bdea524e5c382cd7e48&callback=JSON_CALLBACK';
httpq.get(url2).then(function (data2) {
var userid=data2.data[0].id;
console.log(username+': ' + userid);
value2=''+value2+'';
})
}
text+=value2+' ';
});
console.log('text: ' + text);
items.push(text);
});
$scope.messages = items;
});
});
but the controller doesn't wait for the 2nd http calls(url2), here is the code:
httpq.get(url2).then(function (data2) {
//console.log("data2:"+data2.data[0].id);
var userid=data2.data[0].id;
console.log(username+': ' + userid);
value2=''+value2+'';
//console.log('str: ' + value2);
})
Here is the running demo
Any help would be much appreciated. Best Regards.
I have a factory which get data from server. In the factory method I have used $cacheFactory to cache getting data. My code is as follows..
var buyersService = function ($http, $q,$cacheFactory) {
var serviceBase = '/api/OMData/';
var BuyersFactory = {};
buyersService.cache = $cacheFactory('cacheId');
BuyersFactory.GetBuyers = function () {
var dataList = buyersService.cache.get('BuyerData');
if (dataList != null && dataList.length > 0) {
return dataList;
}
else {
return $http.get(serviceBase + 'GetBuyers').then(
function (results) {
buyersService.cache.put("BuyerData", results.data);
return results.data;
});
}
}
app.factory('OMDataService', ['$http', '$q', '$cacheFactory', buyersService]);
});
Now I have called GetBuyers method from controller. My method is like below..
var BuyerController = function ($scope, BuyersService) {
$scope.Buyers = [];
init();
function init() {
getBuyers();
}
function getBuyers() {
BuyersService.GetBuyers()
.then(function (data) {
$scope.Buyers = data;
}, function (error) {
alert(error.message);
});
}
};
app.register.controller('BuyersController', ['$scope', 'OMDataService', BuyerController]);
When I have executed my controller method second time I have got an error message in promise part.
Object doesn't support property or method 'then'
The issue here is that your function returns two different things: either a promise or plain data. To remedy this, use another promise to control the flow and return that one as the result of the function.
Update your code to
var buyersService = function ($http, $q,$cacheFactory) {
var serviceBase = '/api/OMData/';
var BuyersFactory = {};
buyersService.cache = $cacheFactory('cacheId');
BuyersFactory.GetBuyers = function () {
var buyersDataIsAvailable = $q.defer();
var dataList = buyersService.cache.get('BuyerData');
if (dataList != null && dataList.length > 0) {
buyersDataIsAvailable.resolve(dataList);
}
else {
$http.get(serviceBase + 'GetBuyers').then(
function (results) {
buyersService.cache.put("BuyerData", results.data);
buyersDataIsAvailable.resolve(results.data);
});
}
return buyersDataIsAvailable.promise;
}
app.factory('OMDataService', ['$http', '$q', '$cacheFactory', buyersService]);
});
I start with angularJS and I don't understant how you can push a variable from the controller to a service.
I try with $rootScope but the value of the variable was undefined
here is my service :
technoServices.factory('Config',['$rootScope','$resource',
function($rootScope,$resource,token){
return $resource('../../rest/config',null,{
get: {
method:'GET',
headers:{'X-Token':""+$rootScope.headers},
isArray:false}
});
}]);
and here is my controller :
var technoControllers = angular.module('technoControllers', []);
technoControllers.controller('loginCtrl', ['$scope','$rootScope', 'Techno',function($scope,$rootScope, Techno) {
$scope.getXtoken = function (user,psw){
$scope.config = Techno.post({username:user,password:psw},function(response,headers){
$scope.status= response.status;
$rootScope.headers = headers('X-Token');
if($rootScope.headers != null){
$scope.log = true;
}else{
$scope.log = false;
}
})};
}
]);
technoControllers.controller('configCtrl', ['$scope', 'Config', function($scope, Config) {
$scope.getConfig = function (){
$scope.maConfig = Config.get();
}
So as you can see , I need the variable from the response header of my first service in the header request of my seconde service. How can I do it ?
You can just use another service as shared service which will have the value and inject in both the controller and service.
Code snippet would be like this.
technoServices.factory('Shared',
function(){
var Shared={};
Shared.setValue=function(header){
Shared.header = header;
}
Shared.getValue=function(){
return Shared.header;
}
return Shared;
});
And in controller you can use as
technoControllers.controller('loginCtrl', ['$scope','$rootScope', 'Techno',function($scope,$rootScope, Techno, Shared) {
$scope.getXtoken = function (user,psw){
$scope.config = Techno.post({username:user,password:psw},function(response,headers){
$scope.status= response.status;
Shared.setValue(headers('X-Token'));
//$rootScope.headers = headers('X-Token');
if($rootScope.headers != null){
$scope.log = true;
}else{
$scope.log = false;
}
})};
}
]);
You can inject Shared service in Config to get data
technoServices.factory('Config',['$rootScope','$resource','Shared'
function($rootScope,$resource,token,Shared){
return $resource('../../rest/config',null,{
get: {
method:'GET',
//headers:{'X-Token':""+$rootScope.headers},
headers:{'X-Token':""+Shared.getValue()},
isArray:false}
});
}]);