Angular.js: $http request with JSON as response doesn't work - json

it's my first app with Angular.js and I've searched so hardly but I can't find a solution:
I've got a search form that makes a request to a web server which retrieves a JSON object; the problem is that this request fails and the error function begins.
Here my code:
$scope.queryUser = {};
$scope.url = "http://xxxx:8080/MyApp/search.do?index=central&query=";
$scope.search = function(query) {
$scope.queryUser= angular.copy(query);
// Create the http post request
// the data holds the keywords
// The request is a JSON request.
$http.post($scope.url + $scope.queryUser.value).
success(function(data, status) {
$scope.status = status;
$scope.data = JSON.stringify(data);
$scope.result = data; // Show result from server in our <pre></pre> element
console.log(data);
})
.
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
console.log($scope.data);
});
and this is a sample response:
{"Workstation, Laptop#Workstation$$Laptop":[{"values":{"instanceid":"OI-4A35F9C31E114FBCB5B7668FC5E1FFB4","classid":"COMPUTERSYSTEM"},"index":"distributed"},{"values":{"instanceid":"OI-6A03793A658E45EE90E589D82B0D0962","classid":"COMPUTERSYSTEM"},"index":"distributed"}]}
Any suggestions?
Thanks in advance

I understood the problem: this is a problem of domain. Making the request calling the same webservlet it works...calling an external server it doesn't work.
DOH! I'm sorry for the question

Related

CouchDb 2.1.1 Admin API Compaction PUT Request

I am working in NodeJS with CouchDB 2.1.1.
I'm using the http.request() method to set various config settings using the CouchDB API.
Here's their API reference, yes, I've read it:
Configuration API
Here's an example of a working request to set the logging level:
const http = require('http');
var configOptions = {
host: 'localhost',
path: '/_node/couchdb#localhost/_config/',
port:5984,
header: {
'Content-Type': 'application/json'
}
};
function setLogLevel(){
configOptions.path = configOptions.path+'log/level';
configOptions.method = 'PUT';
var responseString = '';
var req = http.request(configOptions, function(res){
res.on("data", function (data) {
responseString += data;
});
res.on("end", function () {
console.log("oldLogLevel: " + responseString);
});
});
var data = '\"critical\"';
req.write(data);
req.end();
}
setLogLevel();
I had to escape all the quotes and such, which was expected.
Now I'm trying to get CouchDb to accept a setting for compaction.
The problem is that I'm attempting to replicate this same request to a different setting but that setting doesn't have a simple structure, though it appears to be "just a String" as well.
The CouchDB API is yelling at me about invalid JSON formats and I've tried a boatload of escape sequences and attempts to parse the JSON in various ways to get it to behave the way I think it should.
I can use Chrome's Advanced Rest Client to send this payload, and it is successful:
Request Method: PUT
Request URL: http://localhost:5984/_node/couchdb#localhost/_config/compactions/_default
Request Body: "[{db_fragmentation, \"70%\"}, {view_fragmentation, \"60%\"}, {from, \"23:00\"}, {to, \"04:00\"}]"
This returns a "200 OK"
When I execute the following function in my node app, I get a response of:
{"error":"bad_request","reason":"invalid UTF-8 JSON"}
function setCompaction(){
configOptions.path = configOptions.path+'compactions/_default';
configOptions.method = 'PUT';
var responseString = '';
var req = http.request(configOptions, function(res){
res.on("data", function (data) {
responseString += data;
});
res.on("end", function () {
console.log("oldCompaction: " + responseString);
});
});
var data = "\"[{db_fragmentation, \"70%\"}, {view_fragmentation, \"60%\"}, {from, \"23:00\"}, {to, \"04:00\"}]\"";
req.write(data);
req.end();
}
Can someone point at what I'm missing here?
Thanks in advance.
You need to use node's JSON module to prepare the data for transport:
var data = '[{db_fragmentation, "70%"}, {view_fragmentation, "60%"}, {from, "23:00"}, {to, "04:00"}]';
// Show the formatted data for the requests' payload.
JSON.stringify(data);
> '"[{db_fragmentation, \\"70%\\"}, {view_fragmentation, \\"60%\\"}, {from, \\"23:
00\\"}, {to, \\"04:00\\"}]"'
// Format data for the payload.
req.write(JSON.stringify(data));

Sending nested object via post request

I'm running this little node express server, which is supposed to check if the voucher is valid later and then send an answer back to the client
this is my code
app.post('/voucher', function (request, response) {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Request-Method', '*');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', 'authorization, content-type');
if ( request.method === 'OPTIONS' ) {
response.writeHead(200);
response.end();
return;
}
console.log(request)
let results;
let body = [];
request.on('data', function(chunk) {
body.push(chunk);
}).on('end', function() {
results = Buffer.concat(body).toString();
// results = JSON.parse(results);
console.log('#### CHECKING VOUCHER ####', results)
let success = {success: true, voucher: {name: results,
xxx: 10}}
success = qs.escape(JSON.stringify(success))
response.end(success)
} )
}
);
It is obviously just an example and the actual check is not implemented yet. So far so good.
Now on the client side where I work with REACT, I can not seem to decode the string I just send there.
there I'm doing this
var voucherchecker = $.post('http://localhost:8080/voucher', code , function(res) {
console.log(res)
let x = JSON.parse(res)
console.log(x)
console.log(qs.unescape(x))
It gives me the error
Uncaught SyntaxError: Unexpected token % in JSON at position 0
When I do it the other way arround
let x = qs.unescape(res)
console.log(x)
console.log(JSON.parse(x))
Than it tells me
Uncaught TypeError: _querystring2.default.unescape is not a function
Maybe you can help me? I don't know what the issue is here. Thank you.
Also another question on this behalf, since I'm only a beginner. Is there smarter ways to do such things than I'm doing it now? I have react which renders on the client and I have a mini express server which interacts a few times with it during the payment process.
The both run on different ports.
What would be the standard way or best practice to do such things?
I'm a bit perplexed as to why your backend code has so much going on in the request.
Since you asked for if there is a different way to write this, I will share with you how I would write it.
Server
It seems that you want your requests to enable CORS, it also seems that you originally wanted to parse a JSON in your request body.
This is how I would recommend you re-write your endpoint
POST /voucher to take a request with body JSON
{
code: "xxxxx"
}
and respond with
{
success: true,
voucher: {
name: results,
xxx: 10
}
}
I would recommend you use express's middleware feature as you will probably use CORS and parse JSON in most your requests so in your project I would.
npm install body-parser
npm install cors
then in your app initialization
var bodyParser = require('body-parser')
var cors = require('cors')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json you can choose to just pars raw text as well
app.use(bodyParser.json())
// this will set Access-Control-Allow-Origin * similar for all response headers
app.use(cors())
You can read more about body-parser and cors in their respective repos, if you don't want to use them I would still recommend you use your own middleware in order to reduse future redundancy in your code.
So far this will substitute this part of your code
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Request-Method', '*');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', 'authorization, content-type');
if ( request.method === 'OPTIONS' ) {
response.writeHead(200);
response.end();
return;
}
console.log(request)
let results;
let body = [];
request.on('data', function(chunk) {
body.push(chunk);
}).on('end', function() {
results = Buffer.concat(body).toString();
// results = JSON.parse(results);
Now your route definition can just be
app.post('/voucher', function (request, response) {
var result = request.body.code // added by body-parser
console.log('#### CHECKING VOUCHER ####', result)
// express 4+ is smart enough to send this as json
response.status(200).send({
success: true,
voucher: {
name: results,
xxx: 10
}
})
})
Client
your client side can then be, assuming $ is jquery's post function
var body = {
code: code
}
$.post('http://localhost:8080/voucher', body).then(function(res) {
console.log(res)
console.log(res.data)
return res.data
})

Ionic Framework using JSONP and the WordPress JSON-API

I am currently playing with wpIonic (https://github.com/scottopolis/wpIonic) and the sample uses WP-JSON-API V2 (https://wordpress.org/plugins/rest-api/), but I have heavly bespoked another WP API for my needs (https://wordpress.org/plugins/json-api/).
The problem I am having, the wpIonic sample uses JSONP and I am getting the following error
Uncaught SyntaxError: Unexpected token :
http://preview.meeko.me/api/get_posts/?post_type=product&custom_fields=all&_jsonp=JSONP
Object {data: undefined, status: 404, config: Object, statusText: "error"}
The API i am currently using doesn't output JSONP but the DataLoader factory for GET requests does:
.factory('DataLoader', function( $http ) {
return {
get: function(url) {
// Simple index lookup
return $http.jsonp( url );
}
}
})
This is the request to get the post data in my controller:
var postsApi = $rootScope.url + '/api/get_posts/?post_type=product&custom_fields=all&' + $rootScope.callback;
$scope.moreItems = false;
$scope.loadPosts = function() {
// Get all of our posts
DataLoader.get( postsApi ).then(function(response) {
$scope.posts = response.data;
$scope.moreItems = true;
//$log.log(response.data);
}, function(response) {
$log.error(response);
});
}
API & Callback
$rootScope.url = 'http://preview.meeko.me';
$rootScope.callback = '_jsonp=JSON_CALLBACK';
Any guidence in the right direction will be greatly appreciated
Am having the same issues
i think the problem is from json-rest-api as a lot of other people are having the same issues with the V2
using $http.get(....).success().error();
works fine for me!

Node Express 4 get header in middleware missing

I have a middleware function using Node's Express4 to log each request & response for debugging. I use the res.json call in the request handler to send back JSON to the client for all but static files. So I do not want to log the response for static files, but only the JSON responses. I have the following code:
function logRequests(req, res, next) {
// do logging (will show user name before authentication)
logger.reqLog('IN '+req.method+' '+req.url, req);
var oldEnd = res.end,
oldWrite = res.write,
chunks = [];
res.write = function(chunk) {
chunks.push(chunk);
oldWrite.apply(res, arguments);
};
res.end = function(chunk, encoding) {
if(chunk) {
chunks.push(chunk);
}
oldEnd.apply(res, arguments);
// the content-type prints "undefined" in some cases
// even though the browser shows it returned as "application/json"
console.log('type='+res.get('content-type'));
if(res.get('content-type') === 'application/json') {
var body = Buffer.concat(chunks).toString('utf8');
logger.info(body, req);
}
logger.reqLog('OUT '+req.method+' '+req.path, req);
};
next(); // make sure we go to the next routes and don't stop here
}
So why do some requests show the correct content type in the middleware meaning they also print the response fine and others do not? All of them look good in the REST client when inspecting the returned headers.
EDIT: Some more info discovered tonight while trying to figure this out - if I append any character as a dummy request parameter, it logs the response type correctly:
http://localhost:8081/node/ionmed/api/logout?0 WORKS
where
http://localhost:8081/node/ionmed/api/logout DOES NOT
Also, I can always get a response type logging in the middleware function if I replace the .json() call with .end() so this:
res.json({ item: 'logout', success: true });
becomes:
res.set('content-type', 'application/json');
res.end({ item: 'logout', success: true });

Node: Basic JSON request

I'm a complete beginner in Node.js and I wanted to consult something I could not figure out.
Even though I've researched extensively I could not find any method to receive JSON request without using a plugin. I will be using it to program a mobile application API. But even though I've incluede parameter request I cannot reach the content by using request.body, or request.data. The request I'm trying to make is;
{
"id":"123"
}
And my failing code is;
var http = require('http');
function onRequest(request, response){
console.log("Request: "+request.data+"\n");
response.writeHead(200, {"Content-Type":"text/plain"});
response.write("Hello, World");
response.end();
}
http.createServer(onRequest).listen(8888);
The problem here is that you're not listening to the request events to let you know that you have data, and then parsing the data. You're assuming that request has request.data.
It should be:
var http = require('http');
function onRequest(request, response){
var data = '';
request.setEncoding('utf8');
// Request received data.
request.on('data', function(chunk) {
data += chunk;
});
// The end of the request was reached. Handle the data now.
request.on('end', function() {
console.log("Request: "+data+"\n");
response.writeHead(200, {"Content-Type":"text/plain"});
response.write("Hello, World");
response.end();
});
}
http.createServer(onRequest).listen(8888);
See this for the documentation for the methods that request contains.