How to get a desireble output with util.inspect? - javascript

Hi,
I have this code:
var gameon = 1;
var fighter1 = {"userid":"97","username":"john","items":{},"ailments":{}};
var fighter2 = {"userid":"91","username":"james","items":{},"ailments":{}};
var resume = 30;
all = {gameon:gameon,fighter1:fighter1,fighter2:fighter2,resume:resume,inturn:fighter1,outturn:fighter2};
fs.writeFileSync(file, util.inspect(all, { showHidden: true, depth: null }), { encoding: 'utf8', flag: 'w' });
I expect to have the next output written to file:
{
"gameon":1,
"fighter1":{
"userid":"97",
"username":"john",
"items": {},
"ailments":{}
},
"fighter2":{
"userid":"91",
"username":"james",
"items":{},
"ailments":{}
},
"resume":"",
"inturn":{
"userid":"97",
"username":"john",
"items":{},
"ailments":{}
},
"outturn":{
"userid":"91",
"username":"james",
"items":{},
"ailments":{}
}
however, the keys are output without the quotes which will later result into errors when reading the JSON file back. Why is that? How can I customize it so it looks like my expected output?
Thank you.

Related

WKWebView evaluateJavaScript returns wrong JavaScript Object

I'm making a hybrid app and using WKWebView.
I need to pass a JavaScript Object to the emitter command to open the edit dialog.
Here is my code:
let statDict: [String: Any] = [
"income" : account.stat.income,
"expense" : account.stat.expense,
"summary" : account.stat.summary,
"incomeShorten" : account.stat.incomeShorten,
"expenseShorten" : account.stat.expenseShorten,
"summaryShorten": account.stat.summaryShorten
]
let accountDict: [String: Any] = [
"id": account.id,
"name": account.name,
"description": "",
"icon": account.icon,
"currency": account.currency,
"customer_contact_id": account.customer_contact_id ?? 0,
"is_archived": account.is_archived,
"sort": account.sort,
"create_datetime": account.create_datetime,
"update_datetime": account.update_datetime ?? "",
"stat": statDict
]
let accountData = try! JSONSerialization.data(withJSONObject: accountDict, options: JSONSerialization.WritingOptions(rawValue: 0))
guard let accountString = String(data: accountData, encoding: .utf8) else {
return
}
webView.evaluateJavaScript("function parse(string){ return JSON.parse(string)}") { result, error in
if error == nil { // this is returns correct staff
}
}
webView.evaluateJavaScript("parse('\(accountString)')") { object, error in
if error == nil {
let object = object as AnyObject
print("parse object \(object)")
webView.evaluateJavaScript("window.emitter.emit('openDialog', 'Account', \(object))") { (result, error) in
if error == nil { // here the error "Unexpected token '='..."
webView.evaluateJavaScript("window.emitter.on('closeDialog', function(){ window.webkit.messageHandlers.emitterMessage.postMessage('closeDialog'); })") { (result, error) in
if error == nil {
}
}
webView.evaluateJavaScript("window.emitter.on('createAccount', function(){ window.webkit.messageHandlers.emitterMessage.postMessage('createAccount'); })") { (result, error) in
if error == nil {
}
}
} else {
print(error as Any)
}
}
}
}
The \ (object) returned by the function looks like this:
{
"create_datetime" = "2021-08-24 19:19:28";
currency = RUB;
"customer_contact_id" = 1;
description = "";
icon = "";
id = 7;
"is_archived" = 0;
name = "Business 111";
sort = 0;
stat = {
expense = 0;
expenseShorten = 0;
income = 300000;
incomeShorten = 300K;
summary = 300000;
summaryShorten = 300K;
};
"update_datetime" = "";
}
but it should look like this:
{
create_datetime: "2021-08-24 19:19:28",
currency: "RUB",
customer_contact_id: 1,
description: "",
icon: "",
id: 7,
is_archived: false,
name: "Business 111",
sort: 0,
stat: {
expense: 0,
expenseShorten: "0",
income: 300000,
incomeShorten: "300K",
summary: 300000,
summaryShorten: "300K"
},
update_datetime: ""
}
With such an object, the compiler generates the error Unexpected token '='. Expected an identifier as property name.
The parse (string) function will return the correct object if you run it in the js compiler, but in swift the output is not correct.
How to bring an object to the correct form?
You are trying to pass the string interpolated representation of a Swift object (NSMutableDictionary in your case) to Javascript.
Instead you can directly pass the JSON representation to JS context since JSON is a native Javascript object it should do what you are trying to achieve :
/// Sample emitter function that consumes object an prints its local parameter, also assigns it to sample object value in window.
self.webView?.evaluateJavaScript(
"window.emitter = (sampleObject) => { window.sampleObject = sampleObject;setTimeout(function(){console.log('Hello sampleObject : ',sampleObject.name); }, 7000);}"
) { result, error in
if error == nil { // this is returns correct staff
}
}
self.webView?.evaluateJavaScript("window.emitter(\(accountString));") { result, error in
if error == nil {
print("parse object \(result)")
}
}
Result in window :

How to reset JSON after send correctly?

I am trying to build a basic single-page web shop (images of the products, onclick = "addtocart()" and a button "Buy" onclick="buyprem()".
On buy, the JSON is sent to my Java Application via a Websocket.
After buying, I want to reset the JSON representing the order. But whenever I do this, the default JSON is sent.
json = {
products: [],
composite: false,
premium: false,
}
i = 0;
function addtocart(name) {
setTimeout(function() {
var elem = document.getElementById(name);
elem.innerHTML = "";
}, 2000);
document.getElementById(name).innerHTML = i;
json.products[i] = name;
i = i + 1;
}
function buyprem() {
json.premium = true;
var websocket = new WebSocket("ws://localhost:4444");
console.log(JSON.stringify(json))
websocket.onopen = () => {
websocket.send(JSON.stringify(json));
}
//--------------------------
json = {
products: [],
composite: false,
premium: false,
}
i = 0;
//--------------------------
websocket.close;
}
When I comment the marked part out, everything works fine and Java gets the correct JSON.
But when I reset the json variable in this way, Java gets:
Message from client: {"products":[],"composite":false,"premium":false}
(With marked code commented out:
Message from client: {"products":["dog","donatello","twitch"],"composite":false,"premium":true}
where dog, donatello and twitch are the names of the products)
better to do:
function buyprem()
{
json.premium = true
let StrJSON = JSON.stringify(json)
json.products.length = 0
json.composite = false
json.premium = false
i = 0
var websocket = new WebSocket("ws://localhost:4444");
console.log(StrJSON)
websocket.onopen = () =>
{
websocket.send(StrJSON);
}
//--------------------------
websocket.close();
}
because
json = {
products: [],
composite: false,
premium: false,
}
i = 0;
use new memory for json
(in JS, json is a pointer )

Mental JSON cartwheels, match values by key

I have this JSON object:
{
"foo" : {
"58eedc4298d1712b870c8e0a" : false,
"58eedc4298d1712b870c8e06" : true,
"58eedc4198d1712b870c8e05" : true
},
"bar" : {
"58eedc4298d1712b870c8e0a" : "git",
"58eedc4298d1712b870c8e06" : "svn",
"58eedc4198d1712b870c8e05" : "hg"
},
}
I want to get an object that looks like:
{
git: false,
svn: true,
hg: true
}
every algorithm I have come up with is very verbose, anybody think of something quick and clever?
var newObj = {};
for (let property in obj.bar) {
if obj.bar.hasOwnProperty(property){
newObj[obj.bar[property]] = obj.foo[property];
}
}
I'm really not a js dev, but this is where I would start.
The code above is written without any kind of syntax checking. I have no idea if it will actually compile.
If you are using lodash (if not you should), you can do in following way.
var _ = require("lodash");
var data = {
"foo": {
"58eedc4298d1712b870c8e0a": false,
"58eedc4298d1712b870c8e06": true,
"58eedc4198d1712b870c8e05": true
},
"bar": {
"58eedc4298d1712b870c8e0a": "git",
"58eedc4298d1712b870c8e06": "svn",
"58eedc4198d1712b870c8e05": "hg",
"58eedc4198d1712b870c8e06": "fa"
},
}
var keys = _.keys(data.bar);
var result = {};
_.forEach(keys, function (key) {
result[data.bar[key]] = data.foo[key] ? data.foo[key] : false;
});
console.log(result);

How is it possible for a string to be typed as Number in npm package commandLineArgs

In the below code from MongoDB's course Week 3's Query Operators in the Node.js Driver chapter :
var MongoClient = require('mongodb').MongoClient,
commandLineArgs = require('command-line-args'),
assert = require('assert');
var options = commandLineOptions();
MongoClient.connect('mongodb://localhost:27017/crunchbase', function(err, db) {
assert.equal(err, null);
console.log("Successfully connected to MongoDB.");
var query = queryDocument(options);
var projection = {
"_id": 1,
"name": 1,
"founded_year": 1,
"number_of_employees": 1,
"crunchbase_url": 1
};
var cursor = db.collection('companies').find(query, projection);
var numMatches = 0;
cursor.forEach(
function(doc) {
numMatches = numMatches + 1;
console.log(doc);
},
function(err) {
assert.equal(err, null);
console.log("Our query was:" + JSON.stringify(query));
console.log("Matching documents: " + numMatches);
return db.close();
}
);
});
function queryDocument(options) {
console.log(options);
var query = {
"founded_year": {
"$gte": options.firstYear,
"$lte": options.lastYear
}
};
if ("employees" in options) {
query.number_of_employees = {
"$gte": options.employees
};
}
return query;
}
function commandLineOptions() {
var cli = commandLineArgs([{
name: "firstYear",
alias: "f",
type: Number
}, {
name: "lastYear",
alias: "l",
type: Number
}, {
name: "employees",
alias: "e",
type: Number
}]);
var options = cli.parse()
if (!(("firstYear" in options) && ("lastYear" in options))) {
console.log(cli.getUsage({
title: "Usage",
description: "The first two options below are required. The rest are optional."
}));
process.exit();
}
return options;
}
I'm requiring command-line-args package, which has a method commandLineArgs. All good and fine...
Now, I see that the type of the objects passed to this method is set to Number. We can clearly see that they're Strings.
How is it possible?
From the command-line-args GitHub page:
The type value is a setter function (you receive the output from this), enabling you to be specific about the type and value received.
In other words, passing Number as type allows you to parse the arguments as numbers.

Make a new object from a multiple record parse.com object

I need to make a new object out of a multiple record parse.com object in javascript.
This is how I get the entire fetched object:
function(articleID, callback) {
"use strict";
var Comment = Parse.Object.extend('Comment');
var query = new Parse.Query(Comment);
query.descending('createdAt');
query.equalTo('commentFor', {__type:"Pointer", className:"Article", objectId:articleID});
query.equalTo('commentApproved', true);
query.find().then(function(results) {
callback(results);
}, function(error){
callback({error: error});
});
}
Now, the problem is, that this returns (callback()) an object which contains some sensitive data, such as the emails of all commenters, so I want to return a new object with, say, just 'name', 'date', and 'comment'. I just don't know how to build an object like this with a multiple record object as the master.
I am making this in node.js, if that helps in any way.
I'd like something along the line of
[
{
"name": "Robert",
"date": "2016-01-18T17:59:27.378Z",
"comment": "Hello World!"
},
{
"name": "Bob",
"date": "2016-01-15T16:37:35.226Z",
"comment": "Bees knees"
}
]
I've tried this, but it doesn't seem to work - I don't get the output I'd expect:
var test = function(articleID, callback) {
"use strict";
var Comment = Parse.Object.extend('Comment');
var query = new Parse.Query(Comment);
query.descending('createdAt');
query.equalTo('commentFor', {__type:"Pointer", className:"Article", objectId:articleID});
query.equalTo('commentApproved', true);
query.find().then(function(results) {
var object = {};
for(var i = 0; i < results.length; i++) {
object += {
commentName: results[i].get('commentName'),
commentWebsite: results[i].get('commentWebsite'),
commentContent: results[i].get('commentContent'),
createdAt: results[i].get('createdAt')
};
}
callback(object);
}, function(error){
callback({error: error});
});
};
And then I discovered query.select()
This is a case of RTFM! https://parse.com/docs/js/guide#queries-query-constraints

Categories