JSON.stringify comes back empty? - javascript

I'm trying to json serialize an array as follows:
function postToDrupal(contacts, source, owner) {
(function ($) {
var contact, name, email, entry;
var emails = [];
var post_object = {};
for (var i = 0; i < contacts.length; i++) {
contact = contacts[i];
emails[i] = {};
emails[i]['name'] = contact.fullName();
emails[i]['email'] = contact.selectedEmail();
console.log(contacts.length)
}
post_object['emails']=emails;
post_object['source']=source;
post_object['owner']=owner;
$.post("/cloudsponge-post",JSON.stringify(post_object),function(data) {
window.location.href = "/after-import";
});
}(jQuery));
}
The problem is, the post comes back empty. Without JSON.stringify() I get all the elements (but there are thousands of them, which can hit some servers limits, so they need to be serialized). Any help would be much appreciated.

The problem was this. When the request to the server is of type JSON, it's not strictly a POST, so PHP does not populate the $_POST field. In order to retrieve the data, it must be read directly from the request, in other words, instead of using $_POST, use:
$data=file_get_contents("php://input");

You don't need to call JSON.stringify, $.post accepts an object, check $.post.
Code to post just a few emails at a time :
function postToDrupal(contacts, source, owner) {
var pending = 0, limit = 10;
var post_patch = function(emails) {
var post_object = {};
post_object['emails']=emails;
post_object['source']=source;
post_object['owner']=owner;
pending++;
$.post("/cloudsponge-post", post_object,function(data) {
if(pending-- == 0) {
window.location.href = "/after-import";
}
});
}
(function ($) {
var contact, emails = [];
for (var i = 0; i < contacts.length; i++) {
contact = contacts[i];
emails[i] = {};
emails[i]['name'] = contact.fullName();
emails[i]['email'] = contact.selectedEmail();
console.log(contacts.length)
if(limit-- == 0) {
limit = 10
post_patch(emails);
contact = null; emails = {};
}
}
}(jQuery));
}

Related

How can I iterate through multiple URLs to fetch JSON response in Google Apps Script?

I am working with a third-party API (from company called Simpli.fi) in Google Apps Script to pull some data into a spreadsheet. I am able to authenticate my API call just fine and can pull all of my required data with one URL. The issue is that the way the URL to call this API is formatted is as follows:
https://app.simpli.fi/api/organizations/{CLIENT_ID}/{SOME_ENDPOINT}
It works when I plug in one client id and one endpoint, however I do not want to pull the data individually for each client with each data endpoint.
I wish to pull data on all of my clients and also wish to access multiple endpoints, such as "/audiences" or "/campaigns". I am hoping there is a way (similar to Promises in JavaScript) that I can iterate through multiple URLs to fetch all of the data from the API.
For now, I am simply focusing on pulling all the data I want from the "/audiences" endpoint for all of my clients. I have set up an array accessing my Google Sheet that contains all the client codes and have plugged this into the URL with a for loop, which works just fine:
// iterate through all URL endpoints and client codes
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('formatting');
var range = sheet.getRange(['B2:B']).getValues();
var clients = range.filter(String);
var urlOneArray = [];
for (var i = 0; i < clients.length; i++) {
var urlOne = [baseURL + clients[i] + '/audiences'];
for (var j = 0; j < urlOne.length; j++) {
urlOneArray = urlOne[j];
Logger.log(urlOneArray);
}
}
The above logs a list of each built out URL as desired.
After pushing all of the built-out URLs into the urlOneArray, I tried calling with UrlFetchApp.fetchAll:
for (i=0; i < urlOneArray.length; i++) {
var response = UrlFetchApp.fetchAll(urlOneArray[i], params);
Utilities.sleep(500);
Logger.log(response);
}
When trying to use this method, I receive this error:
"Cannot find method fetchAll(string,object). (line 35, file "Code")"
If there is a way to iterate through multiple URLs to gather all of the data from the API in one pull, I would really appreciate some pointers.
Here is the full script:
// authenticate API call
var X_USER_KEY = 'XXXX';
var X_APP_KEY = 'XXXX';
function simplifiService() {
var baseURL = 'https://app.simpli.fi/api/organizations';
// iterate through all URL endpoints and client codes
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('formatting');
var range = sheet.getRange(['B2:B']).getValues();
var clients = range.filter(String);
var urlOneArray = [];
for (var i = 0; i < clients.length; i++) {
var urlOne = [baseURL + clients[i] + '/audiences'];
for (var j = 0; j < urlOne.length; j++) {
urlOneArray = urlOne[j];
Logger.log(urlOneArray);
}
}
var params = {
method: 'GET',
headers: {
"x-app-key": X_APP_KEY,
"x-user-key": X_USER_KEY
},
muteHttpExceptions: true
}
for (i=0; i < urlOneArray.length; i++) {
var response = UrlFetchApp.fetchAll(urlOneArray[i], params);
Utilities.sleep(500);
Logger.log(response);
}
if (response.getResponseCode() === 200) {
var data = JSON.parse(response);
Logger.log(data);
} else {
Logger.log('Error: ' + response.getResponseCode());
}
getData(data);
}
// parse out JSON data
function getData(data) {
var date = new Date();
var geoFenceId = data.audiences;
var geoFenceName = data.audiences[0].name;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Campaign Data');
//sheet.appendRow([date, geoFenceId, geoFenceName]);
}
Issue:
Invalid syntax: UrlFetchApp.fetchAll(requests Object[]) accepts object array, while you're providing a string and a object as argument.
Solution:
Valid Syntax: Create a object array for each endpoint/client and provide it as a argument to fetchAll()
Snippet:
function copyParams() {//shallow clone params object
for (var i in params) {
this[i] = params[i];
}
}
var endPoints = ['/audiences', '/campaigns'];
var requests = [];
var url, obj;
clients.forEach(function(client) {
endPoints.forEach(function(endPoint) {
obj = new copyParams();
url = baseUrl + '/' + client[0] + endPoint;
obj.url = url;
requests.push(obj);
});
});
console.log(requests);
var responseArray = UrlFetchApp.fetchAll(requests);
console.log(responseArray);
References:
UrlFetchApp.fetchAll
Array#forEach

HTMLCollection() Values and Names to JSON

Problem:
Two forms, in hidden divs, which appear when you press the coressponding button. The Input gets parsed to JSON and sent with a request.
I can't use form or fieldset to wrap around the form for different reasons, so I used:
form = document.getElementById('formularEins').getElementsByTagName('input');
When I was still able to use form.elements (before I realised that the .elements property is not supported on fieldsets by IE) I used this to generate JSON from the input:
(In this case form = document.getElementsByClassName('formOne')[0];
Const formToJSON = elements => [].reduce.call(elements, (data, element) => {
if (isCheckbox(element)) {
//data[element.name] = (data[element.name] || []).concat(element.value);
data[element.name] = element.value;
} else if (isMultiSelect(element)) {
data[element.name] = getSelectValues(element);
} else {
data[element.name] = element.value;
}
}
return data;
},);
Question:
How can you convert the Input to JSON for a HTMLCollection and its items like above?
I tried - and failed with different versions of the following:
var formToJSON = function formToJSON(form) {
for (var i = 0; i < form.length; i++) {
var item = form[i];
data[item.name] = item.value; }
};
You have to define data variable as object. Try following formToJSON function.
var formToJSON = function(form) {
var data = {};
for (var i = 0; i < form.length; i++) {
var item = form[i];
data[item.name] = item.value;
}
return data;
}

Build JavaScript Options Array From Multiple Returned Values

I am trying to build a baseline JS file to include in my some of my pages to return information from my SharePoint site. I would like to make three ajax calls to the server for the following: siteGroups, siteRoles and currentUser information and build an options array that I can use later by accessing it using dot notation. (e.g. options.siteGroup, options.siteRoles, options.currentUser.UserName, etc)
var options = (function(){
var currentUser = (function(){
var userInfo = [];
function complete(data){
for(i = 0; i < data.d.Groups.results.length; i++){
var user = {groupId : data.d.results[i].groupId, groupName :
data.d.results[i].groupName, UserName : data.d.UserName, UserId :
data.d.UserId};
UserInfo.push(user);
}
};
getCurrentUser(url, query, complete);
return userInfo;
})();
// Get All Site Permission Groups
var siteGroups = (function(){
function complete(data){
var siteGroups = [];
for(j = 0; j < data.d.results.length; j++){
var group = {groupName : data.d.results[j].Title, groupId :
data.d.results[j].Id};
siteGroups.push(group);
};
$('.SiteGroups').append(option);
};
getSiteGroups(url, complete);
return siteGroups;
})();
// Get All Role Definitions to be used for role assignment
var siteRoles = (function(){
var roles = [];
function complete(data){
var option;
for(s = 0; s < data.d.results.length; s++){
var role = {roleId : data.d.results[s].Id, roleName :
data.d.results[s].Name};
roles.push(role);
}
}
getRoleDefinitions(url, complete);
return roles;
})();
return {currentUser, siteRoles, siteGroups};
})();
When I console.log(options); I get an array with the correct values, however every combination (options.currentUser, options.currentUser.userName, etc) has yielded either userName is undefined or currentUser[0] cannot find value at position 0. Appreciate the help in advance!
http://imgur.com/Ubtb5nD "Image of console.log"

Alias fields for JSON parse

Users on my homepage can upload json fields which I need to parse. I am looking for specific fields which may have a lot of alias names. I am not sure what I should do to check for these alias names.
What I am doing right now is nothing else than checking all possible properties via if/else, but I assume there are much better options for my situation:
function tryParseHeaders(data) {
var header = null
var normalizedHeader = {}
if(data.Header)
header = data.Header
else if(data.header)
header = data.header
else if(data.Headers)
header = data.Headers
else if (data.headers)
header = data.header
if(header.ProjectIdVersion)
normalizedHeader.projectVersion = header.ProjectIdVersion
else if(header.ProjectVersion)
normalizedHeader.projectVersion = header.ProjectVersion
else if(header.Version)
normalizedHeader.projectVersion = header.Version
return normalizedHeader
}
You could use the hasOwnProperty function and then access the object as a dictionary:
function tryParseHeaders(data) {
var index = 0;
var normalizedHeader = {}
var headerAliases = ["Header", "header", "Headers"];
var versionIdAliases = ["ProjectIdVersion", "ProjectVersion", "Version"];
for(index = 0; index < headerAliases.length; index++) {
if(data.hasOwnProperty(headerAliases[index])) {
normalizedHeader.header = data[headerAliases[index]];
}
}
for(index = 0; index < versionIdAliases.length; index++) {
if(data.hasOwnProperty(versionIdAliases[index])) {
normalizedHeader.projectVersion = data[versionIdAliases[index]];
}
}
return normalizedHeader;
}

nested javascript queries in parse

I have the code below. Basically I have 3 nested parse queries. One is getting a number of "followers" and for each follower I am getting a number of "ideas" and for each idea I would like to get that idea creator's name (a user in the user table).
The first two nested queries work but then when i try to get the name of the user (the creator of the idea), that last nested query DOES NOT execute in order. That query is skipped, and then it is executed later in the code. Why is this happening please?
var iMax = 20;
var jMax = 10;
var IdeaList = new Array();
var IdeaListCounter = 0;
var myuser = Parse.User.current();
var Followers = new Parse.Query("Followers");
Followers.equalTo("Source_User",{__type: "Pointer",className: "_User",objectId: myuser.id});
Followers.find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
var object = results[i];
var Ideas = new Parse.Query("Ideas");
Ideas.equalTo("objectId_User", {__type: "Pointer",className: "_User",objectId: object.get('Destination_User').id});
Ideas.find({
success: function(results2) {
for (i=0;i<iMax;i++) {
IdeaList[i]=new Array();
for (j=0;j<jMax;j++) {
IdeaList[i][j]=0;
}
}
for (var j = 0; j < results2.length; j++) {
var object2 = results2[j];
var ideausername2 = "";
IdeaListCounter++;
var ideausername = new Parse.Query("User");
ideausername.equalTo("objectId",object2.get('objectId_User').id);
ideausername.first({
success: function(ideausernameresult) {
ideausername2 = ideausernameresult.get("name");
}
});
IdeaList[IdeaListCounter,0] = object2.get('objectId_User').id + " " + ideausername2; //sourceuser
IdeaList[IdeaListCounter,1] = object2.get('IdeaText'); //text
IdeaList[IdeaListCounter,2] = object2.get('IdeaImage'); //image
IdeaList[IdeaListCounter,3] = object2.get('IdeaLikes'); //likes
IdeaList[IdeaListCounter,4] = object2.get('IdeaReport'); //reports
Your nested query is asynchronous.
Check out the answer at the following for guidance:
Nested queries using javascript in cloud code (Parse.com)

Categories