AngularJs http request concats my data into a JSON key - javascript

Sometimes a behavior is so bizarre that I don't even know how to begin to google it. I'm fairly new at Angular, and I am trying to send POST data to my node server from the client. Here is the controller on the client side:
var app = angular.module("groomer", []);
app.controller("gCtrl", function($scope, $http) {
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$scope.send = function() {
$http({
method : "POST",
url : "/gUpdate",
data: {
gName:$scope.gName,
gPhone:$scope.gPhone,
gWebsite:$scope.gWebsite,
gEmail:$scope.gEmail,
gCustAcct:$scope.gCustAcct,
gAddress:$scope.gAddress,
gNotes:$scope.gNotes
}
}).then(function success(response) {
alert(console.log('Success!'));
}, function error(response) {
alert(console.log('Booooooo'));
});
};
});
What I naively imagine ought to show up at the server is:
req.body = {
gName:'a',
gPhone:'b',
gWebsite:'c',
gEmail:'d',
gCustAcct:'e',
gAddress:'f',
gNotes:'g'
}
But things get weird. What actually shows up at the server as the request body is:
{"{\"gName\":\"a\",\"gPhone\":\"b\",\"gWebsite\":\"c\",\"gEmail\":\"d\",\"gCustAcct\":\"e\",\"gAddress\":\"f\",\"gNotes\":\"g\"}":""}
In case it takes you a second to see what's happening here, that's all of my JSON keys and data in an object, double-quoted, escaped, concatenated as a string, and passed to the server inside an object as a JSON key corresponding to an empty value.
//so
var lifeMakesSense = {gName:'a',gPhone:'b',gWebsite:'c',gEmail:'d',gCustAcct:'e',gAddress:'f',gNotes:'g'}
//becomes
var waitNo = "{\"gName\":\"a\",\"gPhone\":\"b\",\"gWebsite\":\"c\",\"gEmail\":\"d\",\"gCustAcct\":\"e\",\"gAddress\":\"f\",\"gNotes\":\"g\"}"
//then
var whatEven = {waitNo:""} // nailed it
Thoughts?

Related

Not Able to receive data from api server( with public ip) using ngReouce

I know this question in naive, but i stuck and new to angular. I search enough but not able to comeup with solution.
var app=angular.module('myApp',['ngResource']);
app.controller('myCtrl',['$scope','$resource',function ($scope,$resource) {
// body...
var data= $resource('http://ip/category/something',{"p1":76,"p3":9}, { charge: { method: 'POST' } });
console.log(data);
}]);
I am not able to fetch the data from the server and it return a function.
I need explanation if it is possible.
the problem you have is that the $resource service isnt a function that returns data from a request, it returns a $resource object, that has predefined methods to make those requests.
heres how you should do it to get what your looking for
var app=angular.module('myApp',['ngResource']);
app.controller('myCtrl',['$scope','$resource','$q',function($scope,$resource,$q) {
// body...
var data,
dataResource = $resource('http://ip/category/something',{"p1":76,"p3":9}, { charge: { method: 'POST' } });
data = dataResource.get();
$q.when(data.$promise).then(function(){
console.log(data);
});
}])
```
or something like that.

Angularjs Flickr API SyntaxError: Unexpected token when using nojsoncallback=1

I have an angularjs app to call a flickr api.
I want the data in RAW json format with no function wrapper and as per the docs, applying &nojsoncallback=1 .
However I'm getting the following console error. SyntaxError: Unexpected token '
This error only appears when applying &nojsoncallback=1 to the url. However I want RAW json with no wrapper.
If I don't apply the above to the url and simple use https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json I get no error, but when console logging out the typeof I get 'string' displayed.
I then try parsing this into JSON and get another error because it has a wrapped. Hence why I want RAW.
Below is the code I have so far. Any help - much appreciated.
JS
(function(){
'use strict';
var app = angular.module('flickrApp', []);
app.controller('FlickrFeedController', ['$http', '$scope', function($http, $scope){
// grab the flickr api
var response = $http.get('http://crossorigin.me/https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json&nojsoncallback=1');
// on success
response.success(function(data){
// console logging out the typeof gives 'string'
console.log(typeof(data));
// since it's a string I would then want to convert it into a json object
// but I need to sort the current error out first
// data = JSON.parse(data);
// console.log(typeof(data));
});
}]);
})();
EDIT:
This is a work around removing &nojsoncallback=1 from the url (removing the console error) and since the data comes back as a string having to replace characters, then parse. Not great but I get the required output (object) and thought I'd add it up here for others to view.
JS
(function(){
'use strict';
var app = angular.module('flickrApp', []);
app.controller('FlickrFeedController', ['$http', '$scope', function($http, $scope){
// grab the flickr api
var response = $http.get('http://crossorigin.me/https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json');
// on success
response.success(function(data){
// typeOf is 'string' even though format=json is specified in the url
//console.log(typeof(data));
//console.log(data);
// work-around since data is returned as a string
data = data.replace('jsonFlickrFeed(', '');
data = data.replace('})', '}');
data = data.replace(/\\'/g, "'");
// parse the data
data = JSON.parse(data);
// typeOf is 'object'
console.log(data.items);
console.log(typeof(data));
});
}]);
})();
Generate angular resource to call the api with format: {'json', jsoncallback: 'JSON_CALLBACK'}. Check complete solution here - http://plnkr.co/edit/Lxxkb9?p=preview
var app = angular.module('flickrApp', ['ngResource']);
app.factory('Flickr', function($resource, $q) {
var photosPublic = $resource('http://crossorigin.me/https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json',
{ format: 'json', jsoncallback: 'JSON_CALLBACK' },
{ 'load': { 'method': 'JSONP' } });
return {
get: function() {
var q = $q.defer();
photosPublic.load(function(resp) {
q.resolve(resp);
console.log(resp.items);
})
return q.promise;
}
}
});
app.controller('FlickrCtrl', function($scope, Flickr) {
Flickr.get();
});

How to bind an http service to a variable in angularjs when server data changes?

I use an http get request in angular for extract data in a object with the users connected at the moment in my app.
But that info need to be refreshed every time for bind to the scope.
So I made this for refresh every 3 seconds the data of the array in get request ->
index.jade
a(ng-repeat="item in room.connected")
img(src="/images/{{item.avatar}}")
controller.js
ngApp.controller('controller', function(){
var vm = this; vm.connected;
$interval(function(){
//The Get request returns an array like->[{"username":"cesarodriguez4","avatar":"icon-user-man-1.png"}]
$http.get('http://localhost:3000/get-classroom-viewers/user')
.then(function(response){
vm.connected = response.data;
},function(error){
console.log(error);
});
}, 3000);
//Every 3 seconds executes the GET request.
});
That works, but i think its not the correct,
because the terminal shows every time the get request and I think that's a bad practice
Does an method for refresh the info only when the server changes the data?
I try Using $scope.$watch but does not work.
You should use websockets, so that if anything changes in the server side you can push to sockets, from socket you can read and update the scope variable. Looping or making server request on every 3 sec is bad practice as it increases server load.
SockJS Angular Client
angular.module('myApp')
.service('PushNotificationService', ['$q', '$timeout', function($q, $timeout) {
var service = {}, listener = $q.defer(), socket = {
client: null,
stomp: null
};
service.RECONNECT_TIMEOUT = 30000;
service.SOCKET_URL = 'your socket Url'; // like '/chat'
service.CHAT_TOPIC = 'topic url'; // like '/getMessage/chat'
service.receive = function() {
return listener.promise;
};
var reconnect = function() {
$timeout(function() {
initialize();
}, this.RECONNECT_TIMEOUT);
};
var startListener = function() {
socket.stomp.subscribe(service.CHAT_TOPIC, function(data) {
var jsonObj = JSON.parse(data.body);
listener.notify(jsonObj);
});
};
var initialize = function() {
socket.client = new SockJS(service.SOCKET_URL);
socket.stomp = Stomp.over(socket.client);
socket.stomp.connect({}, startListener);
socket.stomp.onclose = reconnect;
};
initialize();
return service;
}]);
In your controller
angular.module('myApp').controller('myCtrl', function($scope, PushNotificationService) {
PushNotificationService.receive().then(null, null, function(message) {
//message contains data you pushed to socket from server
//assign data to $scope variable
$scope.data = message;
});
})
Include below scripts in your html
sockjs.js
stomp.js
More Info
Websocket using Spring AngularJS SockJS

Angularjs firing request without request data

First of all my apologies if the question is repeated.
I am making ajax requests using $q service.
UtilityService.requestCall('/test/encrypt-data', {'json_string' : data_to_encrypt, 'encryption_key' : window.localStorage.getItem("Mi_Encryption_Key")})
.then(function(encrypt_response) {
var requestConoce = parseInt(window.localStorage.getItem("Mi_Cnonce")) + 1;
window.localStorage.setItem("Mi_Cnonce", requestConoce);
requestData['cnonce'] = requestConoce;
requestData['encrypted_data'] = encrypt_response.data;
return UtilityService.requestCall($scope.apiDetails.url, requestData, 'GET');
})
.then(function(api_response) {
var requestConoce = parseInt(window.localStorage.getItem("Mi_Cnonce")) + 1;
window.localStorage.setItem("Mi_Cnonce", requestConoce);
return UtilityService.requestCall('/test/decrypt-data', {'encrypted_string' : api_response.encrypted_data, 'encryption_key' : window.localStorage.getItem('Mi_Encryption_Key') });
})
.then(function(decrypt_response) {
$scope.serverResponse = JSON.stringify(decrypt_response);
return;
})
.catch(function(error) {
alert("Some Error");
})
MyApp.factory('UtilityService', ['$http', '$q', function($http, $q) {
return {
requestCall: function(requestUrl, requestData, methodType) {
var deferred = $q.defer();
var serverUrl = window.localStorage.getItem("Mi_Server_Url");
$http({
method: (methodType) ? methodType : "POST",
url: serverUrl + requestUrl,
data: requestData
})
.then(function(result) {
deferred.resolve(result.data);
},
function(error) {
deferred.reject(error);
});
return deferred.promise;
}
};}]);
I am making requests using the above code. It is working fine for the request "/test/encrypt-data"
But then request for $scope.apiDetails.url is not working. Request is made without any parameters But, I am sending all required parameters in requestData.
This code working for other (even I am sending the data) but not working for this request.
It seems angularjs requests two time for the same request once without data and other with data.
Please help for this strange issue. Please take a look on these images these are showing two different requests once with data and other without data.
First of all you are getting two requests because one of them is the OPTIONS call and one is the actual POST call. This is the normal behaviour and nothing to worry about.
The second request you are making is a GET request which cannot contain any POST-Data. This is just not supported by HTTP.
So depending on what the backend is expecting you could either turn that request into a POST request or you could add the data as GET parameters which is described here: in the Angular docs

ngResource retrive unique ID from POST response after $save()

So I have a Resource defined as follows:
angular.module('questionService', ['ngResource'])
.factory('QuestionService', function($http, $resource) {
var QuestionService = $resource('/api/questions/:key', {}, {
query: {
method:'GET',
isArray:true,
},
save: {
method: 'POST',
}
});
return QuestionService
});
And later on I take some form input and do the following
var newQ = {
txt: $scope.addTxt
};
QuestionService.save(newQ)
The server responds to the POST request both by reissuing the JSON for the object and setting the location header with the new unique ID. The problem is that Angular is not saving that returned JSON or the location header into the object and it is not getting set with the ID from the server for future operations. I've tried a number of things such as:
transformResponse: function(data, headersGetter) {
locationHeader = headersGetter().location;
key = locationHeader.split('/').slice(-1)[0];
data.key = key;
return data;
}
However the returned data item doesn't seem to be getting used. Am I missing something? This seems like a pretty common use case for interacting with a REST api.
Thanks!
You need to have a success handler to assign the new id to newQ manually:
QuestionService.save(newQ, function(data) {
newQ.id = data.id;
});
But there is a better to achieve the same. Because your QuestionService is a resource class object, you can instantiate your newQ like this:
var newQ = new QuestionService({text: $scope.addTxt});
Then, call $save() of newQ:
newQ.$save();
Now newQ should have the new id returned by the server.
I have Asp.Net server with WebApi2 running, i use Ok(number) to return content, and it return for example '6' as result. once it return, the angular show an object containing promise and state, and prototypes and a deep repeated hierarchy, but no value, no '6'.
So i went to see where the data goes, for seeing where the data is i define a transform, and i see awo the data, but it's not a json...
later i change it to following, and now i have a obj in my success function, which has sub property called 'returnValue' (as i defined), and this object hold my value.
transformResponse: function(data, header){
var obj={};
obj.returnValue=angular.fromJson(data);
return obj;
},

Categories

Resources