I am currently trying to have a script that I can use in order to turn google sheet data into json that can include neighboring AND nested objects. Currently what I have is a script that can allow for the sheet data to turn into json that allows for nesting objects BUT it does not allow the ability to end one object and start a new one so there cannot be any neighboring objects and instead there's one parent object with children objects in it which is not what I'm after. I'm hoping that I'm just missing something in the current script in order to be able to end and start new objects so I will add the script below, thank you for any contributions to this question!
function formJSON() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var data = sheet.getDataRange().getValues();
var currentObject = {};
var output = currentObject;
for (var i = 0; i < data.length; i++) {
if (data[i][1]) {
currentObject[data[i][0]] = data[i][1];
}
else {
var newObject = {};
currentObject[data[i][0]] = newObject;
currentObject = newObject;
}
}
Logger.log(JSON.stringify(output));
}
EDIT: Here I will provide the current result vs the result I'm after. The first result is from the sheet I have added as an image.
Current Result:
{
"": {
"asset": {
"button": {
"viewPDF": "View PDF",
"viewSurvey": "View Survey",
"viewPPT": "View PPT",
"viewLink": "View Link",
"rejoinMeeting": "Rejoing Meeting",
"labels": {
"associatedWith": "Associated Content",
"attendees": "Attendees in this session",
"filesAndDocs": "Files and Documents",
"location": "Location",
"messages": {
"errorRetrieving": "There was an error retrieving the session details",
"noAttendees": "Nobody is watching this session currently",
"browser": {
"messages": {
"notSupported": "Your browser is not supported",
"update": "Please update"
}
}
}
}
}
}
}
}
Desired Result:
"asset": {
"buttons": {
"viewPDF": "View PDF",
"viewSurvey": "View Web Page",
"viewPPT": "View Presentation",
"viewLink": "View Link",
"rejoinMeeting": "Rejoin Meeting"
},
"labels": {
"associatedWith": "Associated Content",
"attendees": "Attendees in this Session",
"filesAndDocs": "Files and Documents",
"location": "Location",
"notStarted": "This session hasn't started yet.",
"playlist": "Session Playlist",
"premiumSponsors": "Premium Sponsors",
},
"messages": {
"errorRetrieving": "There was an error retrieving the session details.",
"noAttendees": "Nobody is watching this session currently",
"pointsForDocument": "viewing a document",
"pointsForRatingAsset": "rating this asset",
"pointsForVideo": "watching a video",
"problemSaving": "There was a problem saving your rating. Please try again."
}
},
"browser": {
"messages": {
"notSupported": "Your Browser Is Not Supported",
"update": "Please download the most up-to date version of one of the following and try again"
}
},
Please have a look at the following:
var data = sheet.getDataRange().getValues();
var currentObject = {};
var title ='';
var newObject = {};
for (var i = 0; i < data.length; i++) {
if (data[i][1]) {
newObject[data[i][0]] = data[i][1];
}
else {
if(data[i][0] !="" && data[i][0] !=" "){
if(title != ""){
currentObject[title] = newObject;
}
title = data[i][0];
newObject = {};
}
}
}
Logger.log(JSON.stringify(currentObject));
While this is not a full solution, I think that it should point you into the right direciton.
The idea is that you should have some variable (in this case title) which is defined / overwriten in the else statement and which is the key to which nested objects will be assigned during the next if conditions
Once the else condition is entered again, title is overwritten wiht the next nested object key.
Related
In my piece of code below I receive a JSON object from a java Servlet and access the properties of that object.
JSON object:
{
"redirect": "/index.html",
"logout": "/_cloudshellProxy/_ah/logout?continue\u003d%2Findex.html",
"status": true,
"register": true,
"user": {
"email": "s#example.com",
"username": "Yevesky",
"college": {
"name": "Lafayette College",
"key": "aglzcHN0ZWFtMTlyFAsSB0NvbGxlZ2UYgICAgICAswgM"
},
"key": "aglzcHN0ZWFtMTlyEQsSBFVzZXIYgICAgICgxAgM"
}
}
Here is how I handle the object from the servlet.
fetch("/getUserInfo").then(response => response.json()).then(object =>
{
jsonObject = object;
console.log(jsonObject);
setUpUserPage(jsonObject);
loadClasses();
});
function setUpUserPage(json){
const jsonData = json;
var name = document.createElement("h3");
name.innerText = String(jsonData.username);
var uni = document.createElement("h6");
uni.innerText = String(jsonData.college.name); // Error occurs here
var classification = document.createElement("h6");
console.log(jsonData.classes);
if (jsonData?.isProf)
{
classification.innerText = "Professor";
}
else
{
classification.innerText = "Student";
}
var email = document.createElement("h6");
email.innerText = String(jsonData.email);
var spacer = document.createElement("BR");
//change nickname link
var changeNicknameP = document.createElement("p");
changeNicknameP.innerText = "Change your nickname: ";
var anchor = document.createElement("A");
var link = document.createTextNode("here");
anchor.setAttribute("href", "#");
anchor.appendChild(link);
changeNicknameP.appendChild(anchor);
var profileContainer = document.getElementById("profile-container");
profileContainer.appendChild(name);
profileContainer.appendChild(uni);
profileContainer.appendChild(classification);
profileContainer.appendChild(email);
profileContainer.appendChild(spacer);
profileContainer.appendChild(changeNicknameP);
}
The problem is I do not understand why I am getting a "TypeError: Cannot read property 'name' of undefined" if the object has such a property?
Is it just JavaScript or I am not following a procedure.
I do print the JSON object on console everytime to see if indeed the property exist.
This is because you probably made a mistake. "college" is a property of user, not your jsonData. Replace your line with this :
uni.innerText = String(jsonData.user.college.name);
Don't forget to check properties of your object if response can change (for example is user or college are optionnal properties in some case)
PS: sorry I can't post a comment because I dont have enough point on SO.
So I have this code that someone had posted from awhile back. It has been working flawlessly for a year now. It takes the google form answers and posts them to discord channel as a webhook. Now since yesterday, it is not working anymore. Nothing has changed with the script.
function onSubmit(e) {
var form = FormApp.getActiveForm();
var POST_URL = "****";
var allResponses = form.getResponses();
var latestResponse = allResponses[allResponses.length - 1];
var response = latestResponse.getItemResponses();
var items = [];
for (var i = 0; i < response.length; i++) {
var question = response[i].getItem().getTitle();
var answer = response[i].getResponse();
try {
var parts = answer.match(/[\s\S]{1,1024}/g) || [];
} catch (e) {
var parts = answer;
}
if (answer == "") {
continue;
}
for (var j = 0; j < parts.length; j++) {
if (j == 0) {
items.push({
"name": question,
"value": parts[j],
"inline": false
});
} else {
items.push({
"name": question.concat(" (cont.)"),
"value": parts[j],
"inline": false
});
}
}
}
var options = {
"method":"POST",
"payload": JSON.stringify({
"content":"Hello, World!",
"embeds":[{
"title":"War Times Form",
"fields":items,
"footer":{
"text":"***Please verify these are Correct***"
}
}]
})
};
Logger.log("[METHOD] onFormSubmit");
Logger.log(items);
Logger.log(options);
var response = UrlFetchApp.fetch(POST_URL, options);
Logger.log(response);
};
This is what logging is saying its submitting
[19-11-24 10:13:28:400 PST] {method=POST, payload={"content":"Hello, World!","embeds":[{"title":"War Times Form","fields":[{"name":"Post your clan name:","value":"fds","inline":false},{"name":"Post your name","value":"fds","inline":false},{"name":"Clan that you are declaring against:","value":"dfsa","inline":false},{"name":"Days and times your group is available was HQ fight (must be in EST):","value":"sdaf","inline":false}],"footer":{"text":"***Please verify these are Correct***"}}]}}
However, I keep getting this error:
Request failed for https://discordapp.com returned code 400. Truncated server response: {"message": "Cannot send an empty message", "code": 50006} (use muteHttpExceptions option to examine full response)
at onSubmit(Code:54)
Any help that anyone can give me would be great. I have tried contacting discord support and they wont help as its API/Dev
So found the answer had to add to the options that get sent through the request. Discord apparently changed it and didn't tell anyone that you have to declare it
"contentType" : "application/json",
I want to create Email using MS Dynamics Web API.
Here I am posting data
{
"sender": "test#test.com",
"torecipients": "test2#test.com",
"subject": "Test Subject New 1234567",
"description": "Test Description New 1234567"
}
But sender and torecipients are not reflecting in Dynamics CRM.
Only subject & description are displaying.
Is there anything I am missing?
You have to populate collection valued navigation property email_activity_parties for filling up From & To fields. sender & torecipients are fields just for reporting purpose with emailaddress of those activity parties.
var email = {};
email["subject"] = "Email demo from Web API";
email["description"] = "This a web api test";
email["regardingobjectid_contact#odata.bind"] = "/contacts(C41CE33F-D0A0-E611-811E-5065F38C8781)";
//activityparty collection
var activityparties = [];
//from party
var from = {};
from["partyid_systemuser#odata.bind"] = "/systemusers(8D23B2C1-9869-4C3F-9A80-BA51375C1784)";
from["participationtypemask"] = 1;
//to party
var to = {};
to["partyid_contact#odata.bind"] = "/contacts(C41CE33F-D0A0-E611-811E-5065F38C8781)";
to["participationtypemask"] = 2;
activityparties.push(to);
activityparties.push(from);
//set to and from to email
email["email_activity_parties"] = activityparties;
Read more
Edit:
JSON will look like this:
{
"subject": "Test Subject New 1234567",
"description": "Test Description New 1234567",
"regardingobjectid_contact#odata.bind": "/contacts(<GUID>)",
"email_activity_parties": [
{
"partyid_contact#odata.bind": "/contacts(<GUID>)",
"participationtypemask": 2
},
{
"partyid_systemuser#odata.bind": "/systemusers(<GUID>)",
"participationtypemask": 1
}
]
}
I have this code in my app.js for send chat and read chat in my application
$scope.messageshistory = {};
$scope.tmp = {};
// send message
$scope.sendMessage = function(){
$scope.messages = {
from : $scope.datauser['data']['_id'],
fromname : $scope.datauser['data']['nama'],
to : $scope.tmpuserid,
message : $scope.tmp['sendmessage'],
time : moment()
};
//event emit message
socket.emit('message',$scope.messages,function(callback){
if(!callback['error']){
$scope.messages['time'] = moment($scope.messages['time']).format('DD-MMMM-YYYY HH:MM');
if ($scope.messageshistory.hasOwnProperty($scope.tmpuserid)){ //yg di json yg paling awal
$scope.messageshistory[$scope.tmpuserid].push($scope.messages);
}else{
$scope.messageshistory[$scope.tmpuserid] = [];
$scope.messageshistory[$scope.tmpuserid].push($scope.messages);
}
$scope.tmp['sendmessage'] = '';
}else{
var msg = callback['error'];
navigator.notification.alert(msg,'','Error Report', 'Ok');
}
$scope.$apply();
});
};
//event read message
socket.on('message', function (data) {
window.plugin.notification.local.add({
id : moment(),
title : data['fromname'],
message : data['message'].substr(0,20) + ' ...',
led : 'A0FF05',
json : JSON.stringify({ routes:'chat', nama :data['fromname'],from:data['from'] })
});
data['time'] = moment(data['time']).format('DD-MMMM-YYYY HH:MM');
if ($scope.messageshistory.hasOwnProperty(data['from'])){
$scope.messageshistory[data['from']].push(data);
}else{
$scope.messageshistory[data['from']] = [];
$scope.messageshistory[data['from']].push(data);
}
for(var i = 0; i<= $scope.datauser['data']['friends'].length; i++){
if($scope.datauser['data']['friends'][i]['userid'] == data['from']){
$scope.datauser['data']['friends'][i]['ischat'] = true;
break;
}
};
$scope.$apply();
});
my question is how to take the last value in message property from $scope.messageshistory, because $scope.messages is for sending the message and $scope.messageshistory is to keep the chat history. This is the chat activity image:
just from this activity, $scope.messageshistory will save the data in it JSON as:
{
"5512": [{
"from": "561c",
"fromname": "ryan",
"to": "5512",
"message": "hey",
"time": "18-Maret-2016 21:03"
}, {
"from": "5512",
"fromname": "sasa",
"to": "561c",
"message": "hello",
"time": "18-Maret-2016 21:03",
"_id": "593s"
}]
}
I get this value from using angular.toJson($scope.messageshistory), and this array will always add up if the chat activities still going on. And my intention to get the last value in message property from $scope.messageshistoryis to use in Text-to-Speech feature in my application. This is the code:
$scope.speakText = function() {
TTS.speak({
text: **this the place for the code**,
locale: 'en-GB',
rate: 0.75
}, function () {
// handle the success case
}, function (reason) {
// Handle the error case
});
};
it will read the last message in $scope.messageshistory. So, what code that I must write to take the last value?
You have to do the following:
var msgs = $scope.messageshistory[$scope.tmpuserid]
var yourLastMessage = msgs[msgs.length-1].message
// you could also add a quick check so you don't get
// an error if the messages array is emtpy :
// var yourLastMessage = (msgs && msgs[msgs.length-1] ? msgs[msgs.length-1].message : null)
Edit
Some explanation per your comment :
var msgs = $scope.messageshistory[$scope.tmpuserid]
// msgs is now an Array containing Objects
// [{message : 'xxx'},{message : 'yyy'}]
// we take the last entry of the msgs Array (msgs.length-1)
// so msgs[msgs.length-1] is the last object ({message : 'yyy'})
// and finally we take the 'message' property' of that object:
var yourLastMessage = msgs[msgs.length-1].message
assuming that the keys in the history object are ascending numbers and taking into account that the order of keys in an object is not specified by W3C you will have to do the following:
get all keys
find the "latest" (hence the biggest number)
fetch it
so you could do for example
var keys = Object.keys($scope.messagehistory);
keys.sort (function (a, b) {
return a - b;
});
var result = keys[keys.length - 1];
I am knew to JSON, this is the first time i have worked with it.
I have created a script using node to pull music(Artists and Song Titles) from a radio stations website as the radio station plays them. Currently i am putting them into a JSON file by appending them to the end of the file.
I would like to fill them into an array each time a new song is found instead. How do i go about doing this?
Here is my current code
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var schedule = require('node-schedule');
var rule = new schedule.RecurrenceRule();
//Timer to run every 3 minutes (average song time)
rule.minute = new schedule.Range(0, 59, 3);
var j = schedule.scheduleJob(rule, function(){
console.log('LOADING.......................');
//URL for site you want to get the Songs from
url = '#';
request(url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
var artist, stitle;
var songs = {artist : "", stitle : ""};
//ID for artist
$('#').each(function(){
var data = $(this);
artist = data.text();
songs.artist = artist;
})
//ID for song title
$('#').each(function(){
var data = $(this);
stitle = data.text();
songs.stitle = stitle;
})
}
//Reading current list of songs
var content;
content = fs.readFileSync('output.json', "utf8");
//Searching current list for song it wants to add
var text = content;
var search = text.search(stitle);
//Only adding song if it cant find new song in list
if(search >= 0) {
console.log('Song already exists');
} else {
fs.appendFile('output.json', JSON.stringify(songs, null, 4) + ",\n", function (err) {
console.log('Song successfully added!');
});
}
})
});
Currently my JSON output looks like:
{
"artist": "FOO FIGHTERS",
"stitle": "BEST OF YOU"
},
{
"artist": "GAY NINETIES",
"stitle": "LETTERMAN"
},
{
"artist": "VANCE JOY",
"stitle": "RIPTIDE"
},
{
"artist": "NIRVANA",
"stitle": "IN BLOOM"
}
I would like to fill an array of songs like this:
{
songs : [
{
"artist": "FOO FIGHTERS",
"stitle": "BEST OF YOU"
},
{
"artist": "GAY NINETIES",
"stitle": "LETTERMAN"
},
{
"artist": "VANCE JOY",
"stitle": "RIPTIDE"
},
{
"artist": "NIRVANA",
"stitle": "IN BLOOM"
}
]
}
I know that i need to use something alongs the lines:
var songs = [];
for (var song in songs) {
songs.push({artist : "", stitle : ""});
}
But i don't know how to incorporate into my code, any help would be lovely, thanks guys
Okay, so if I understand your question correctly, you would like to load the JSON data; then append a song into the array; and then convert it back into JSON?
// load new song data first:
var newSong = {
artist: "FOO BAR FIGHTERS",
stitle: "IF THEN ELSE"
}
// then load data:
var jsonString = "[{:[,],:}]" // load JSON file here!
var data = JSON.parse(jsonString) // turn JSON string into an actual object
/*
at this point, you have access to data.song,
which is the array of all songs in the list.
*/
// now check if it's already in the list:
var alreadyInList = false
for(var i = 0; i < data.song.length; i ++)
{
if(data.song[i].stitle === newSong.stitle) alreadyInList = true
}
// if not, push it:
if(!alreadyInList) data.song.push(newSong)
// then stringify the object again for storage:
var backToString = JSON.stringify(data)
console.log(data) // output back to file
Is this what you're looking for?