How to format data for XDomainRequest - javascript

I need to post data to a cross origin web service using json. This works perfectly in ie10+ but not in ie8/9.
After researching i discovered i need to use XDomainRequest but am unsure how to format the data.
For example, can i just wrap a string around my JSON object and send it or does it need to be in name value pairs like?
Im currently sending
{
"field": {
"field": "blah",
"field": "blah",
"field": "blah",
"field": "blah",
"field": [
"ML08BWV",
"MJ08OJF",
"MJ10PYO",
"FT10EXZ",
"SH57XUM"
]}
}
I'm definitely hitting the server but the server logs suggest that im not sending any data in the request payload. :/
Edit: Javascript Code
var xdr = new XDomainRequest(); // Use Microsoft XDR
xdr.open('POST', URL);
xdr.onload = function () {
//xdr.contentType = "application/json";
var dom = new ActiveXObject('Microsoft.XMLDOM'), JSON = $.parseJSON(xdr.responseText);
dom.async = false;
if (JSON == null || typeof (JSON) == 'undefined') {
JSON = $.parseJSON(data.firstChild.textContent);
}
//Do something with json
};
xdr.onerror = function () {
_result = false;
};
xdr.ontimeout = function () {
alert('xdr ontimeout');
};
xdr.onprogress = function () {
alert("XDR onprogress");
alert("Got: " + xdr.responseText);
};
xdr.send("json=" + dataToSend);
dataToSend is in the json format as posted above

Related

Coinmarketcap Authenticated API error: 400 "\"value\" must contain at least one of [id, symbol, slug]",

Using Google Sheets Script I am Attempting to run this function and it does not seem to be recognizing my "qs: {'id': '1'}," Line
Getting result
{
"status": {
"timestamp": "2019-07-15T06:41:31.753Z",
"error_code": 400,
"error_message": "\"value\" must contain at least one of [id, symbol, slug]",
"elapsed": 0,
"credit_count": 0
}
}
My API Key is in
sheet ="Config"
Cell ="B35"
This is not the problem because if I remove the API key it gives an "invalid API error" so I know the address and API are correct.
Im expecting a result as described in the documentation here
https://coinmarketcap.com/api/documentation/v1/#operation/getV1CryptocurrencyQuotesLatest
function test() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Config");
var key = sheet.getRange("B35").getValue()
var options = {
muteHttpExceptions: true,
headers : {'X-CMC_PRO_API_KEY': key},
qs: {'id': '1'},
json: true,
gzip: true
}
var url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest";
var response = UrlFetchApp.fetch(url, options);
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("workingArea01").getRange('!F2').setValue(response);
}
Thankyou to for the Comment. With this Information I was able to make it work by adding the qs: data directly to the end of the url as follows
var options = {
muteHttpExceptions: true,
headers : {'X-CMC_PRO_API_KEY': key},
}
var params = "?&id=1"
var url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest";
var response = UrlFetchApp.fetch(url+params, options);

JavaScript loop to accommodate filtered array of objects received from a webhook

Goal
Capture each event sent through a webhook and turn it into a Slack post. Events include new blog posts, questions, discussions, wiki page, etc. (qualified as contents) and comments (qualified as comments) posted in an online community. Sometimes multiple events are sent in the webhook at once.
Attempted method
This simple JavaScript Azure Function is intended to
Receive one or more webhook events sent in a JSON array
Filter objects qualified as contents from those qualified as comments
Send an API request for each content and/or comment object (both have their own URL endpoint)
Parse each object returned (contents and comments return a similar but different hierarchy of keys)
Assemble the values into JSON objects (one per event, regardless of whether it is a content or comment) and send to Slack
Results
The following code worked fine for a single webhook event until I attempted to add the for loop to accommodate multiple webhook events sent in one array.
Code
Example JSON from webhook
{
"events": [{
"TypeId": "9999-999e",
"DateOccurred": "2018-12-15T20:39:42.2487557Z",
"EventData": {
"ActorUserId": 1234,
"ContentId": "5678-999c",
"ContentTypeId": "9012-999d",
"WikiPageId": 3456,
"WikiId": 1
}
},
{
"TypeId": "1111-111f",
"DateOccurred": "2018-12-15T22:55:37.7846546Z",
"EventData": {
"ActorUserId": 2345,
"ContentId": "2222-222b",
"ContentTypeId": "3333-333a",
"ForumReplyId": 4567,
"ForumThreadId": 8901,
"ForumId": 2
}
},
{
"TypeId": "9012-888f",
"DateOccurred": "2018-12-15T22:44:57.7091846Z",
"EventData": {
"ActorUserId": 9876,
"CommentId": "8900-123a"
}
}
]
}
Example JSON returned from API request
The slightly different structure in hierarchies is accurate.
(for contents)
{
"Content": {
"CreatedByUser": {
"ProfileUrl": "https://<company>.telligenthosting.net/members/<user>",
"Username": "<user>"
},
"HtmlName": "Title",
"HtmlDescription": "Text",
"Url": "https://<company>.telligenthosting.net/<link>"
}
}
(for comments)
{
"Comment": {
"Content": {
"CreatedByUser": {
"ProfileUrl": "https://<company>.telligenthosting.net/members/<user>",
"Username": "<user>"
},
"HtmlName": "Title",
"HtmlDescription": "Text",
"Url": "https://<company>.telligenthosting.net/<link>"
}
}
}
JavaScript file (as an Azure Function)
module.exports = function (context, data) {
var json = data.body;
var request = require('request');
// Parse the webhook event JSON body
var unparsed = JSON.stringify(json.events);
var parsed = JSON.parse(unparsed);
console.log(parsed) // RESULTS ARE AS EXPECTED (the JSON nested beneath `events`, beginning and ending with `[]`)
for (var i = 0; i < parsed.length; i++) {
// Parse out Id of webhook event (for all content types but comments)
// This Id retrieves details about the content
var ContentId, ContentTypeId;
if (parsed[i].EventData.hasOwnProperty('ContentId')) {
var ContentId = parsed[i].EventData.ContentId;
var ContentTypeId = parsed[i].EventData.ContentTypeId;
console.log(ContentTypeId); // RESULTS ARE NOT AS EXPECTED: Prints the same Id twice
var options = {
url: "https://<company>.telligenthosting.net/api.ashx/v2/genericcontent/" + ContentId + "/" + ContentTypeId + ".json",
headers: {
"Rest-User-Token": "<token>",
"Content-Type": "application/json"
}
};
};
// Parse out Id of a webhook event (for comments only)
// This Id retrieves details about a comment
var CommentId;
if (parsed[i].EventData.hasOwnProperty('CommentId')) {
var CommentId = parsed[i].EventData.CommentId;
var options = {
url: "https://<company>.telligenthosting.net/api.ashx/v2/comments/" + CommentId + ".json",
headers: {
"Rest-User-Token": "<token>",
"Content-Type": "application/json"
}
};
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.parse(body);
//For all content types but comments
var username, profileUrl, subject, url, text;
if (info.hasOwnProperty('Content')) {
username = info.Content.CreatedByUser.Username;
profileUrl = info.Content.CreatedByUser.ProfileUrl;
subject = info.Content.HtmlName;
url = info.Content.Url;
text = info.Content.HtmlDescription;
};
//For comments
if (info.hasOwnProperty('Comment')) {
username = info.Comment.User.DisplayName;
profileUrl = info.Comment.User.ProfileUrl;
subject = info.Comment.Content.HtmlName;
url = info.Comment.Url;
text = info.Comment.Body;
};
};
//Send to Slack
function sendToSlack(theUsername, theIconEmoji) {
var theUsername = "Bot";
var theIconEmoji = ":bot:";
var payload = {
attachments: [{
author_name: username,
author_link: profileUrl,
title: subject,
title_link: url,
text: text
}]
};
if (theUsername !== undefined) {
payload.username = theUsername;
}
if (theIconEmoji !== undefined) {
payload.icon_emoji = theIconEmoji;
}
var theRequest = {
url: urlWebHook,
method: "POST",
json: payload
};
request(theRequest, function (error, response, body) {});
}
var urlWebHook = "https://hooks.slack.com/services/<Id>";
sendToSlack();
};
};
request(options, callback);
};
Issue
As commented out in the code above, it appears that the loop is not going through each event but rather through the first event multiple times.
Much of what I read indicates for (var i = 0; i < json.length; i++) { is the proper approach but no matter what I try the Azure Function throws a 500 Internal Service Error and eventually times out. No information is provided in the debug console even though detailed logging is turned on.
Thank you
Thank you for any advice or education.
EventData is not defined because you're not constructing your object properly.
Here's how you might do it:
var json = require("./test.json");
var unparsedEvents = json.events;
for (let event of unparsedEvents) {
var ContentId = event.EventData.ContentId;
var ContentTypeId = event.EventData.ContentTypeId;
var CommentId = event.EventData.CommentId;
var options = new Object();
console.log("ContentId:", ContentId);
console.log("ContentTypeId:", ContentTypeId);
console.log("CommentId:", CommentId);
if (CommentId) {
options.url = "https://<company>.telligenthosting.net/api.ashx/v2/comments/" + CommentId + ".json";
options.headers = {
"Rest-User-Token": "<token>",
"Content-Type": "application/json",
};
} else {
options.url = "https://<company>.telligenthosting.net/api.ashx/v2/genericcontent/" + ContentId + "/" + ContentTypeId + ".json";
options.headers = {
"Rest-User-Token": "<token>",
"Content-Type": "application/json",
};
}
console.log("options:", options);
console.log();
}
I believe you need to change parsed[0] to parsed[i]. Currently you are looping through the array but only accessing the first element, which is why you see the first event multiple times.

In a Camunda process, How can I retrieve a boolean value from JSON using JavaScript and Spin?

I have a service task which calls a REST API; the API is returning the following JSON:
{
"success": true,
"message": null,
"details": [],
"errors": [],
"transactions": []
}
The service task has a JavaScript output parameter to process the JSON output:
var statusCode = connector.getVariable("statusCode");
if (statusCode != 200) {
throw new Error(connector.getVariable("response"));
}
else {
var output = S(connector.getVariable("response"));
output.prop("success").value==true; // Problem line
}
I have sent the output to a process variable and confirmed that it contains the JSON above. However, I cannot get this output to ever register as true for the subsequent forking of the process. I have tried all of the following:
output.prop("success");
output.prop("success").value;
output.prop("success").value==true;
output.prop("success").value===true;
output.prop("success").value=="true";
Can anyone help with getting this right?
I got help with this in the Camunda forum here. My code now reads as below, and works as desired:
var statusCode = connector.getVariable("statusCode");
if (statusCode != 200) {
throw new Error(connector.getVariable("response"));
}
else {
var output = S(connector.getVariable("response"), "application/json");
output .prop("success").boolValue();
}

integrating geojson query to generate http requests in angularjs

i am trying to integrate geoshape query from elastic search into my angularjs code to make an http request to fetch the data that is residing on elasticsearch local instance but the console throws error that invalid XMLhttp parameters. I guess it is related to how i am adding the geojson with my URL. Following is the function where i am creating the http request
function spatialsearch() {
var _url = '127.0.0.1:9201/_search?';
var b = {
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"metadata.o2r.spatial.geometry": {
"shape": {
"type": "polygon",
"coordinates": [
[
[-22.0, 76.0],
[-27.0, 65.0],
[-57.0, 65.0],
[-59.0, 76.0],
[-22.0, 76.0]
]
]
},
"relation": "contains"
}
}
}
}
}
};
_url += b;
return $http.get(_url);
console.log("hello");
}
Here is how i am calling http request in my js file in angularjs
function callingspatialsearch(){
var deferred = $q.defer();
httpRequests.
spatialsearch()
.then(cb1)
.catch(errorHandler);
return deferred.promise;
function cb1(response){
$log.debug('result of search: %o', response);
deferred.resolve(response);
}
function errorHandler(e){
$log.debug('search error: %o', e);
deferred.resolve(e);
}
}
In my HTML i am adding a button so that when user clicks on button the results are displayed.
<md-button ng-click="vm.button()" class="search-button md-primary md-raised white-font">Spatial</md-button>
i am using $http.post(_url) instead of GET and that helps me in retrieving results

Backbone parsing this.model.destroy

INTRO
I Am having having issues trying to parse my models before I send them to my web service.
I have a REST web services set-up which is working fine, I have my backbone set-up to parse the web services JSON reponse, which also works fine. I am able to display the JSON objects
The problem is when I try to delete or update the model, backbone never parses the model before it sends it back to the server and the server always receives null.
Here is my code:
Teacher Model
window.Teacher = Backbone.Model.extend({
urlRoot: "http://localhost:8080/SIMS/resource/teacher",
defaults: {
"id": null,
"Name": "",
"Password": "",
"email": "",
"dob": "",
"type": ""
},
parse: function(response){
console.log("................................. response test.........");
response.id = response.idTeacher;
console.log("..........."+response.name);
console.log("..........."+response.idTeacher);
response.Password = response.password;
response.Name = response.name;
delete response.name;
delete response.password;
delete response.idTeacher;
return response;
} ,
toJSON: function(){
var attrs = _.clone(this.attributes);
attrs.name = attrs.Name;
delete attrs.Name;
attrs.password = attrs.Password;
delete attrs.Password;
attrs.idTeacher = attrs.id;
delete attrs.id;
return attrs;
}
});
window.TeacherCollection = Backbone.Collection.extend({
model: Teacher,
url: "http://localhost:8080/SIMS/resource/teacher",
parse: function(response){
for (var i=0; i<response.length; i++)
{
console.log("...........help");
response[i].id = response[i].idTeacher;
response[i].Password = response[i].password;
response[i].Name = response[i].name;
console.log(".........."+response[i].Name);
delete response[i].name;
delete response[i].password;
delete response[i].idTeacher;
}
return response ;
}
});
Teacher View: save function
saveTeacher: function() {
this.model.set({
Name: $('#Name').val(),
email: $('#email').val(),
Password: $('#Password').val(),
dob: $('#dob').val(),
type: $('#type').val()
});
if (this.model.isNew()) {
var self = this;
app.teacherList.create(this.model, {
success: function() {
app.navigate('admin/teacher/'+self.model.id, false);
}
});
} else {
this.model.save();
}
return false;
},
Web Service
#PUT #Path("{id}")
#Consumes({"application/xml", "application/json"})
#Produces({"application/xml", "application/json"})
public void update(Teacher T){
System.out.println("Updating Teacher:" + T.getName());
teacherejb.edit(T);
}
Question
Since I have the parse function I now use .attributes instead of toJSON() and this works fine.
Example:
render: function(eventName) {
$(this.el).html(this.template(this.model.attributes));
return this;
},
But when trying to call this.model.save in the saveteahcer function it never parses before I send it to the server, Im not sure how to parse it first and then send it to the server. When I debug the code the web service always receives null, how do I get my web service to properly receive the teacher object ?
The parse method is called after the server response, see Backbone documentation:
parsemodel.parse(response, options)
parse is called whenever a model's data is returned by the server, in fetch, and save.
I would suggest that you use validate to modify/update the data before send it to server:
validatemodel.validate(attributes, options)
This method is left undefined, and you're encouraged to override it with your custom validation logic, if you have any that can be performed in JavaScript. By default validate is called before save [...]

Categories

Resources