Mobile Application Using Sencha Touch - JSON Request Generates Syntax Error - web-services

I started playing a bit with Sencha Touch.
So I've built a really simple application based on one of the examples just to see how it goes.
Basically it creates a JSON Request which executes a Last.FM web service to get music events near the user's location.
Here's the JSON code:
var makeJSONPRequest = function() {
Ext.util.JSONP.request({
url: 'http://ws.audioscrobbler.com/2.0/',
params: {
method: 'geo.getEvents',
location: 'São+Paulo+-+SP',
format: 'json',
callback: 'callback',
api_key: 'b25b959554ed76058ac220b7b2e0a026'
},
callback: function(result) {
var events = result.data.events;
if (events) {
var html = tpl.applyTemplate(events);
Ext.getCmp('content').update(html);
}
else {
alert('There was an error retrieving the events.');
}
Ext.getCmp('status').setTitle('Events in Sao Paulo, SP');
}
})
};
But every time I try to run it, I get the following exception:
Uncaught SyntaxError: Unexpected token :
Anyone has a clue?

A couple of things. First of all the "Uncaught SyntaxError: Unexpected token :" means the browser javascript engine is complaining about a colon ":" that has been put in the wrong place.
The problem will most likely be in the returned JSON. Since whatever the server returns will be run though the eval("{JSON HTTP RESULT}") function in javascript, the most likely thing is that your problem is in there somewhere.
I've put your code on a little sencha test harness and found a couple of problems with it.
First: My browser was not too happy with the "squiggly ã" in location: 'São+Paulo+-+SP', so I had to change this to location: 'Sao+Paulo,+Brazil', which worked and returned the correct results from the audioscribbler API.
Second: I notice you added a callback: 'callback', line to your request parameters, which changes the nature of the HTTP result and returns the JSON as follows:
callback({ // a function call "callback(" gets added here
"events":{
"event":[
{
"id":"1713341",
"title":"Skank",
"artists":{
"artist":"Skank",
"headliner":"Skank"
},
// blah blah more stuff
"#attr":{
"location":"Sao Paulo, Brazil",
"page":"1",
"totalpages":"1",
"total":"2"
}
}
}) // the object gets wrapped with extra parenthesis here
Instead of doing that I think you should be using the callbackKey: 'callback' that comes with the example in http://dev.sencha.com/deploy/touch/examples/ajax/index.js.
Something like this for example:
Ext.util.JSONP.request({
url: 'http://ws.audioscrobbler.com/2.0/',
params: {
method: 'geo.getEvents',
location: 'Sao+Paulo,+Brazil',
format: 'json',
api_key: 'b25b959554ed76058ac220b7b2e0a026'
},
callbackKey: 'callback',
callback: function(result) {
// Output result to console (Firebug/Chrome/Safari)
console.log(result);
// Handle error logic
if (result.error) {
alert(result.error)
return;
}
// Continue your code
var events = result.data.events;
// ...
}
});
That worked for me so hopefully it'll work for you too. Cherio.

Related

Postman - Cant run pm.sendRequest() in collection level pre-request script

Im using newman to run api tests after build in travis.
Im trying to limit the duplication of pre-request scripts so checked out some workarounds on how can I have pre-request-scripts at collection level.
My problem is that I dont want to run them on every request, only the ones where I need them.
Example: Im trying to run a login script to use the returned token on private endpoints.
My code looks like:
Collection level pre-request script definiton:
Object.prototype.login = function() {
const request = {
url: 'somthing',
method: 'GET',
header: 'Content-Type:application/json',
body: {
mode: 'application/json',
raw: JSON.stringify(
{
email: pm.environment.get('someenv'),
password: pm.environment.get('someenv')
})
}
};
pm.sendRequest(request, function (err, res) {
var response = res.json();
pm.environment.set("token", response.token);
});
}
Request level pre-request script definiton:
_.login();
Can someone help me out why I cant run pm.sendRequest in this scope?
pm.environment.get('someenv') works like a charm, so Im not sure what to do here.
It runs fine when called from Collection level pre-request script without using the Object, but if I just put the whole request there, it will run before every request what I want to avoid in the first place.
I have tried to log some stuff out using console.log(), but it seems that the callback in pm.sendRequest() never runs.
So I have found a workaround for the issue, I hope its going to help out someone in the future :)
So its easy to setup a collection level pre-request that runs before every single request.
But to optimize this a little bit because you dont need to run every script for every request you make in a collection. You can use my solution here. :)
The issue I think is caused by:
PM object used in a different scope is not going to affect the PM object in global scope, so first you should pass global PM object as parameter for function call.
The collection level request should look like this:
login = function (pm) {
const request = {
url: pm.environment.get('base_url') + '/login',
method: 'POST',
header: {
'Content-Type': 'application/json',
},
body: {
mode: 'application/json',
raw: JSON.stringify({
email: pm.environment.get('email'),
password:pm.environment.get('passwd')
})
}
};
pm.sendRequest(request, (err, res) => {
var response = res.json();
pm.expect(err).to.be.a('null');
pm.expect(response).to.have.property('token')
.and.to.not.be.empty;
pm.globals.set("token", response.token);
});
};
And for the exact request where you want to call auth first and use the token for the request call:
login(pm);

Ember - Issue with HTTP POST request

I have written a (very) simple RESTFul Web service to retrieve data from MongoDB using Node, Express and Mongoose.
On the server side, I have this code:
router.route('/products').post(function(req,res){
var product = new Product(req.body);
product.save(function(err){
if(err)
res.send(err);
res.send({message:'Product Added'});
});
When I submit a request from my Ember client, the req.body contains something like the following:
{ attributes:
{ category: 1,
name: 'y',
price: 1,
active: false,
notes: null } }
The attribute names are exactly the same as my mongoose schema. I get no error but the document created in MongoDB is empty (just get the _id and __v fields).
What am I doing wrong. Should I convert the req.body further into ???
A couple things that will help debug:
1) From a quick glance (I haven't used mongoose before) it looks like call back function passed to save takes two arguments.
2) I don't know if your code got cut off, but the sample above was missing a matching });
3) I made the function short circuit itself on error, so you will not see 'Product added' unless that is truly the case.
Try these fixes.
router.route('/products').post(function(req,res){
var product = new Product(req.body);
product.save(function(err, product){
if(err){
return res.send(err);
}
return res.send({message:'Product Added'});
});
});
The issue was related to my lack of familiarity with Ember and Node+Express. The data received in the server is slightly different from what I had first indicated: (first line was missing)
{ product:
{ attributes:
{ category: ... } } }
On the server side I can access my data using req.body.product.attributes (instead of req.body):
router.route('/products').post(function(req,res){
var product = new Product(req.body.product.attributes);
product.save(function(err){
if(err)
res.send(err);
res.send({message:'Product Added'});
});

Parse Cloud Code with facebook API not working properly

I want to get a location Id from facebook API (that is already in my DB) and than use this to get the events from that location.
So, i'm first running a query to get this info and than adding this result as a parameter in my url. The fact is that the query is returning the result properly but when calling the httpRequest this is failling. Its important to say that my httpRequest works when I use the locationId hard coded.
I guess this problem is occuring because of the response calls but i cant figure out how to fix it. I'm also looking on a better way to design this code. Any ideas?
Parse.Cloud.define("hello", function(request, response) {
var query = new Parse.Query("Location");
query.find({
success: function(results) {
locationId = results[0].get("locationFbId");
console.log(locationId);
},
error: function() {
response.error("Failed on getting locationId");
}
});
Parse.Cloud.httpRequest({
url: 'https://graph.facebook.com/v2.2/'+locationId+'/events?access_token='+accessToken,
success: function(httpResponse) {
console.log(httpResponse.data);
response.success("result");
},
error:function(httpResponse){
console.error(httpResponse.message);
response.error("Failed to get events");
}
});
});
Adolfosrs, your problem here is that your two requests are running asynchronously on different threads. Therefore, your first request isn't returning until after your second request has been called. I would suggest chaining the requests as below so that your second request will be initialized with the data retrieved from the first request.
Parse.Cloud.define("hello", function(request, response) {
var query = new Parse.Query("Location");
query.find({
success: function(results) {
locationId = results[0].get("locationFbId");
console.log(locationId);
Parse.Cloud.httpRequest({
url: 'https://graph.facebook.com/v2.2/'+locationId+'/events?access_token='+accessToken,
success: function(httpResponse) {
console.log(httpResponse.data);
response.success("result");
},
error:function(httpResponse){
console.error(httpResponse.message);
response.error("Failed to get events");
}
});
},
error: function() {
response.error("Failed on getting locationId");
}
});
});

Typeahead/Bloodhound - Using Jquery Ajax for remote causes only a single server side request

I need to use a jquery ajax setup in Bloodhound's remote property since I have a server side page that takes POST requests only. Everything works, but just once. Any subsequent change to the text in the typeahead input box calls the filter function, but does not fire a new server side request to fetch new data. It just filters through the data that it got in the first request. I need for it make a new request as the user removes the text and types in something else.
I am new to typeahead and I am spending way too much time trying to figure this out. Here is my code.
var users = new Bloodhound({
datumTokenizer: function (d) {
return Bloodhound.tokenizers.whitespace(d.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: 'fake.jsp',
filter: function (users) {
return $.map(users, function (user) {
return {
value: user.USER_ID,
name: user.DISPLAYNAME
};
});
},
ajax: {
type: 'POST',
data: {
param: function(){
return $('#userid').val();
}
},
context: this
}
}
});
users.initialize(true);
$('#userid').typeahead({
minLength: 3,
highlight: true
}, {
name: 'userslist',
displayKey: 'name',
source: users.ttAdapter()
});
I had the same solution and discovered jQuery's cache: false; option does not work in this situation for whatever reason. Here is the solution I found:
remote: {
url: ...
replace: function(url, query) {
return url + "#" + query; // used to prevent the data from being cached. New requests aren't made without this (cache: false setting in ajax settings doesn't work)
}
}
try this:
remote: {
url: 'fake.jsp/?' + Math.random(),
.
.
.
it's not really the solution but at least the results will be fetched from server everytime the page is refreshed.

Get xhr object in vb.net while ajax calling fails

I have a big problem in jQuery.ajax call. I am calling the web service whenever click the update button. I have a separate web service class, in which consist of few methods. When I calling the web service method, I have made the error handling and log the error information in db after that I have to override the “ex” that means error object to XMLHttpRequest. Is it possible to assign the SqlException to ajax object (xhr) in VB.NET? Please help me its much more useful for me.
Yes it is possible! I try to describe it in VB.NET (mostly I use C#, but I hope I'll not made syntax errors). Let us we have a Web service
<WebMethod()> _
<ScriptMethodAttribute(ResponseFormat:=ResponseFormat.Json, UseHttpGet:=True)> _
Public Function GetData(ByVal Age As Integer) As String
If Age <= 0 Then
Throw(New ArgumentException("The parameter age must be positive."))
End If
'... some code
End Function
The same code in C# look like
[WebMethod]
[ScriptMethod (UseHttpGet=true)]
public string GetData(int age)
{
if (age <= 0)
throw new ArgumentException("The parameter age must be positive.");
// some code
}
In case of negative Age input the exception ArgumentException will be thrown (all what I explain stay the same for another exception like SqlException).
Now you have a JavaScript code which use jQuery.ajax to call the service. Then you can expand the code to support the exception handling in the following way:
$.ajax({
type: "GET",
url: "MyWebService.asmx/GetData",
data: {age: -5},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data, textStatus, xhr) {
// use the data
},
error: function(xhr, textStatus, ex) {
var response = xhr.responseText;
if (response.length > 11 && response.substr(0, 11) === '{"Message":' &&
response.charAt(response.length-1) === '}') {
var exInfo = JSON.parse(response);
var text = "Message=" + exInfo.Message + "\r\n" +
"Exception: " + exInfo.ExceptionType;
// + exInfo.StackTrace;
alert(text);
} else {
alert("error");
}
}
});
In case of exception be thrown, we receive information about error in JSON format. We deserialize it to the object having Message, ExceptionType and StackTrace property and then display error message like following
Message: The parameter age must be positive.
Exception: System.ArgumentException
In a real application you will probably never displayed the value of the StackTrace property. The most important information are in the Message: the text of exception and in ExceptionType: the name of exception (like System.ArgumentException or System.Data.SqlClient.SqlException).