Google Apps Script PropertiesService Unexpected Token in Obj Literal - javascript

I am using Google Apps PropertyService to store some settings variables. When I use the setProperties() function and give it an object (just like they do in the documentation) and then try to get a property and parse it I am getting a SyntaxError: Unexpected Token in Object Literal.
The PropertiesService is emptied before I run this code. As far as I understand I am getting a string back that I should be able to parse into an object.
function setDefaults(){
var def = {
config: {
isSetup: false
},
test: {
page: true
}
}
var docServ = PropertiesService.getDocumentProperties();
docServ.setProperties(def, true);
log(typeof docServ.getProperty("config")); //string
log(docServ.getProperty("config")); //{isSetup=false}
log(JSON.parse(docSer.getProperty("config"))); //SyntaxError
}

It seems that the issue has something to do with multiple nested objects. Apparently, the JSON parser can only go down one level.
Calling JSON.stringify() on each of the nested objects solved the problem for me:
var def = {config: {isSetup: false}, test: {page: true}};
for (var prop in def) {
def[prop] = JSON.stringify(def[prop]);
}
var docServ = PropertiesService.getDocumentProperties();
docServ.setProperties(def, true);
var config = JSON.parse(docServ.getProperty("config"));
Logger.log(config.isSetup); //logs 'false'

Related

How to store multiple items in Chrome Extension Storage? [duplicate]

I'm writing a chrome extension, and I can't store an array. I read that I should use JSON stringify/parse to achieve this, but I have an error using it.
chrome.storage.local.get(null, function(userKeyIds){
if(userKeyIds===null){
userKeyIds = [];
}
var userKeyIdsArray = JSON.parse(userKeyIds);
// Here I have an Uncaught SyntaxError: Unexpected token o
userKeyIdsArray.push({keyPairId: keyPairId,HasBeenUploadedYet: false});
chrome.storage.local.set(JSON.stringify(userKeyIdsArray),function(){
if(chrome.runtime.lastError){
console.log("An error occured : "+chrome.runtime.lastError);
}
else{
chrome.storage.local.get(null, function(userKeyIds){
console.log(userKeyIds)});
}
});
});
How could I store an array of objects like {keyPairId: keyPairId,HasBeenUploadedYet: false} ?
I think you've mistaken localStorage for the new Chrome Storage API.
- You needed JSON strings in case of the localStorage
- You can store objects/arrays directly with the new Storage API
// by passing an object you can define default values e.g.: []
chrome.storage.local.get({userKeyIds: []}, function (result) {
// the input argument is ALWAYS an object containing the queried keys
// so we select the key we need
var userKeyIds = result.userKeyIds;
userKeyIds.push({keyPairId: keyPairId, HasBeenUploadedYet: false});
// set the new array value to the same key
chrome.storage.local.set({userKeyIds: userKeyIds}, function () {
// you can use strings instead of objects
// if you don't want to define default values
chrome.storage.local.get('userKeyIds', function (result) {
console.log(result.userKeyIds)
});
});
});

Javascript - Array is of type object and failing at .push directly after declaration of array

const audio = connection.receiver.createStream(message, { mode: 'pcm', end: 'manual' });
var testingArr = new Array();
audio.on('data', (data) => {
console.log(Array.isArray(testingArr)); //output: false
testingArr.push(data);
});
The body here shows testingArr as not of type array
How is this happening?
I am looking to add the new data to the array as it comes in over a few seconds so I can decrypt it into text strings.
I have also tried var testingArr = [], and encountered the same issue
The Error I get when I attempt to run this script:
TypeError: testingArr.push is not a function
at Decoder.<anonymous>
I accidentally set testingArr to another value outside of the async process farther down in the script.

JS/NodeJS/VSCode - How to step into a console logged object [duplicate]

In the below code (running on Node JS) I am trying to print an object obtained from an external API using JSON.stringify which results in an error:
TypeError: Converting circular structure to JSON
I have looked at the questions on this topic, but none could help. Could some one please suggest:
a) How I could obtain country value from the res object ?
b) How I could print the entire object itself ?
http.get('http://ip-api.com/json', (res) => {
console.log(`Got response: ${res.statusCode}`);
console.log(res.country) // *** Results in Undefined
console.log(JSON.stringify(res)); // *** Resulting in a TypeError: Converting circular structure to JSON
res.resume();
}).on('error', (e) => {
console.log(`Got error: ${e.message}`);
});
Basic console.log will not go through long and complex object, and may decide to just print [Object] instead.
A good way to prevent that in node.js is to use util.inspect:
'use strict';
const util = require('util'),
obj = /*Long and complex object*/;
console.log(util.inspect(obj, {depth: null}));
//depth: null tell util.inspect to open everything until it get to a circular reference, the result can be quite long however.
EDIT: In a pinch (in the REPL for example), a second option is JSON.stringify. No need to require it, but it will break on circular reference instead of printing the fact there is a reference.
Print the whole object, it will not have problems with recursive refferences:
console.log(res);
Here's an example for you to see how console.log handles circular refferences:
> var q = {a:0, b:0}
> q.b = q
> console.log(q)
{ a: 0, b: [Circular] }
Also, I would advise to check what data are you actually receiving.
By using the http request client, I am able to print the JSON object as well as print the country value. Below is my updated code.
var request = require('request');
request('http://ip-api.com/json', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(response.body); // Prints the JSON object
var object = JSON.parse(body);
console.log(object['country']) // Prints the country value from the JSON object
}
});
This can print the key of the object and the value of the object in the simplest way. Just try it.
const jsonObj = {
a: 'somestring',
b: 42,
c: false
};
Array.from(Object.keys(jsonObj)).forEach(function(key){
console.log(key + ":" + jsonObj[key]);
});
In 2021, I just printed using
app.post("/",(req,res) => {
console.log("HI "+JSON.stringify(req.body));
res.send("Hi")
});
and got my output as HI {"Hi":"Hi"}.
I sent
{
"Hi": "Hi"
}
as my post request body.
Only doing console.log(req.body) printed [object Object] on console but now this works.
Use console.dir and set the depth.
console.dir(obj, { depth:10 })
Alternatively you can set the default depth to change the console.log depth.
require('util').inspect.defaultOptions.depth = 10
All of this and details about this can be found in nodejs training.
https://nodejs.dev/learn/how-to-log-an-object-in-nodejs
You do not actually get data in res. You need on('data') and on.('end')
body is a string. It gets append on data received, so on complete you will need to parse data into json
http.get("http://ip-api.com/json", function(res) {
var body = '';
res.on('data', function(data){
body = body + data;
});
res.on('end', function() {
var parsed = {};
try{
parsed = JSON.parse(body); // i have checked its working correctly
}
catch(er){
//do nothing it is already json
}
console.log(parsed.country);
});
});
Noe from parsed which is a json object, you can get any property
You can pass two arguments to console.log()
Try this code after installing "yargs" And it will print whole object
console.log('object is' , yargs.argv);
I think may be it will help you to print whole object :)

Parsing a JavaScript function string

Starting off, I am aware of the security risks storing JavaScript functions in JSON strings, however that is not what is happening here.
Now I am working on a JS multi-threading model using web workers and blob strings. However as I'm sure you are aware you cannot use custom objects or prototypes from said custom objects in web workers so I developed a system for serializing a custom object with functions into an anonymous object that can be used in the web worker however I am getting a syntax error when calling JSON.parse over the serialized object.
Serialize function:
AjaxHandler.prototype.getEmbedded = function(stringify) {
"use strict";
let embMembers = this.metaData.embeddedMembers; // an array of function names to add
let embeddedObj = {};
let stringifyArray = stringify ? new Array(embMembers.length) : [];
if (stringify) {
for (let i = 0; i < embMembers.length; i++) {
stringifyArray[i] = ('"' + embMembers[i] + '":"' + AjaxHandler.prototype[embMembers[i]].toString().replace(/[\n\r]+/gi, '').replace(/[\t]+/gi, '')).replace(/\/\*\*\/this.\/\*\*\//gi, '') + '"';
}
} else {
for (let mem of embMembers) {
embeddedObj[mem] = AjaxHandler.prototype[mem];
}
}
if (stringify) {
return ("{" + stringifyArray.join(",") + "}");
} else {
return embeddedObj;
}
};
All functions being embedded are syntactically correct however when I try to parse it:
!function TestAction() {
"use strict";
let tHandler = new AjaxHandler();
let eme = tHandler.getEmbedded();
let stf = tHandler.getEmbedded(true);
let ptf = JSON.parse(stf); // Throws syntax error
debugger;
}();
It throws an error (Uncaught SyntaxError: Unexpected string) as noted in the code.
Is there a way to parse out the object containing functions?
Notes:
No JSON data is being sent to or from the client so I don't think it's a security risk to store and send a function in JSON.
I have researched previous questions on the matter and none of the leads I found produced any valid solution aside from "don't do it, it's a security risk".

Unable to access element in JSON when keyname is unknown

I'm trying to retrieve the filename of gists on Github, from the data obtained from Github's API. I'm using javascript to access the data.
An example result can be found here: https://api.github.com/users/blaercom/gists. I've also copied a shortened version of the data below.
{
...
id: "4468273",
files: {
firstpost.md: {
type: "text/plain",
filename: "firstpost.md",
size: 16,
language: "Markdown"
}
}
...
}
I've been trying many things, but I can't seem to access the filename. This is because the 'files' object is not a list, but a key-value pair, where the key identifier matches the filename itself.
Things I've tried include
filename = files[0]['filename']
filename = files[0].filename
filename = files['filename']
Frankly, the only methods that work are variations of filename = files['firstpost.md']['filename'] but this isn't valid since I can not know the filename beforehand.
I'm sure it is possible to access the filename, but have been spending quite a while testing different methods. Help would be appreciated!
You can use for (var key in object) {}, here is an example using the data from your api call:
var filenames = [];
for (var filename in data[0].files) {
filenames.push(filename);
}
console.log(filenames); // ["firstpost.md"]
Here is a real example using your json response
var obj='your json data';
var fileNames=[];
for(var i in obj[0]['files'])
{
var fileName=obj[0]['files'][i]['filename'];
fileNames.push(fileName);
}
document.write(fileNames[0]); // firstpost.md
Example.
Update:
Another example using jsonp/script.
<script src="https://api.github.com/users/blaercom/gists?callback=myCallback"></script>
The callback function
function myCallback(o)
{
var obj=o.data;
var fileNames=[];
for(var i in obj[0]['files'])
{
var fileName=obj[0]['files'][i]['filename'];
fileNames.push(fileName);
}
document.write(fileNames[0]); // firstpost.md
}

Categories