Setting a Node.js Object to data read from a file - javascript

I want to read data from a file and add it to an Object stored in memory. The data in the file text.txt looks roughly like this:
One: {title: 'One' ,
contributor: 'Fred',
summary: 'blah' ,
comments: 'words' },
Two: {title: 'Two' ,
contributor: 'Chris' ,
summary: 'blah blah i'm a blah' ,
comments: '' },
I'm trying to set it to an empty Object like so:
var fs = require('fs');
var text = Object.create(null);
fs.readFile("./public/text.txt", "utf-8", function(error, data) {
text = { data };
});
However, when I log text to the console, it comes out looking like this:
{ data: 'One: {title: \'One\' ,\ncontributor: \'Fred\',\nsummary: \'blah\' ,\ncomments: \'words\' },\n \nTwo: {title: \'Two\' ,\ncontributor: \'Chris\' ,\nsummary: \'blah blah i\'m a blah\' ,\ncomments: \'\' },\n\n' }
Apparently, it's reading data as a key. What I really want, though, is something more like so:
{
One: {title: 'One' ,
contributor: 'Fred',
summary: 'blah' ,
comments: 'words' },
Two: {title: 'Two' ,
contributor: 'Chris' ,
summary: 'blah blah i'm a blah' ,
comments: '' },
}
Any advice here would be much appreciated.

If you are using a newer version of Node, then you have support for ES6.
// So your code
`text = { data }`
// is actually a shortcut for
`text = { data: data }`
That's why you end up with an object that has the key data and the value is a string version of what was found in the file. Instead, just use JSON.parse on the data parameter (which is a string) and it'll convert it to an Object, which you can store in text. Like this
var fs = require('fs');
var text = Object.create(null);
fs.readFile("./public/text.txt", "utf-8", function(error, data) {
text = JSON.parse(data);
});
You'll also need to make the file valid json. Which means keys need quotes around them as do String values.
{
"One": {
"title": "One" ,
"contributor": "Fred",
"summary": "blah" ,
"comments": "words"
},
"Two": {
"title": "Two" ,
"contributor": "Chris" ,
"summary": "blah blah i'm a blah" ,
"comments": ""
}
}

What you are trying to do is use eval, which is the only way if you really don't want to edit the file to be valid JSON or to export an object as #Spidy suggested. Just be sure the file is valid JavaScript, because the example you gave had
summary: 'blah blah i'm a blah'
but you need to escape i'm like i\'m.
var fs = require('fs');
var text = {};
fs.readFile('./public/text.txt', 'utf-8', function (error, data) {
eval(`text = {${data}}`);
//eval('text = {' + data + '}');
});
But I wouldn't necessarily recommend that because that allows arbitrary javascript to get executed. Depending on how the data in the file gets there it would be a huge security risk.

Related

How to set table as Postman.variables object

I need to put table as new Postman variable, but I am probably doing something wrong with syntax, because when I try to used initialized table, there is "Unexpected token in JSON" error.
This is my initialization of table:
pm.variables.set("cr", {crypt_arr: [
{
key: "BTC",
used: false
},
{
key: "ETH",
used: false
},
{
key: "XRP",
used: false
}]});
This is how I use this table. Maybe there is something wrong there:
const crypto_arr = JSON.parse(pm.variables.get()).crypt_arr;
const crypto_arr = JSON.parse(pm.variables.get('cr')).crypt_arr;
you have to specify the variable name
Also you don't have to parse it as varible stored as object itself
const crypto_arr = (pm.variables.get('cr')).crypt_arr;

Convert a local text file into object in javascript as user configuration file

I was trying to make a 'save file' so users can download and load their config into the site.
here's what I'm trying to accomplish:
config.txt
projectName: 'Lorem',
timeStarted: '12:21:00',
tasks: [
'Do this',
'Do that',
'Then this',
'Then that'
]
js object
projectName: 'Lorem',
timeStarted: '12:21:00',
tasks: [
'Do this',
'Do that',
'Then this',
'Then that'
]
I've tried the method from this solution using split, map, and reduce but still failing to convert the text into the object
here's my code:
let str = [config.txt];
let output = str.split("\n")
.map(a => a.match(/(.*): '(.*)',/))
.reduce([haven't figured out this part]);
I want the object to have an array inside.
I found the solution by using JSON as follows
//to set the object
var config = {
"projectName": "Lorem",
"timeStarted": "12:21:00",
"tasks": [
"Do this",
"Do that",
"Then this",
"Then that" ]
}
// to convert the object into string
var asString = JSON.stringify(config);
// to process and parse the string back to object
var asObject = JSON.parse(asString);
I wasn't able to use JSON.parse() before because I put the config object as the parameter.

How to compress a YAML file using references in a script?

I am converting a json file to a YAML file with https://github.com/nodeca/js-yaml using safeDump
The outcome is like this
en:
models:
errors:
name: name not found
url: bad url
user:
errors:
name: name not found
url: bad url
photo:
errors:
name: name not found
url: bad url
but I want a script to compress with the references
en:
models:
errors: &1
name: name not found
url: bad url
user:
errors: *1
photo:
errors: *1
Based on the Python script from Anthon https://stackoverflow.com/a/55808583/10103951
function buildRefsJson(inputJson, mappings = null) {
if (!mappings) {
mappings = {}
}
if (typeof(inputJson) === 'object') {
let value
let stringValue
let ref
for (let key in inputJson) {
value = inputJson[key]
stringValue = JSON.stringify(value)
ref = mappings[stringValue]
if (ref) {
inputJson[key] = ref
} else {
mappings[stringValue] = value
buildRefsJson(inputJson[key], mappings)
}
}
}
I transformed it to JavaScript code. And it did the work! Also thanks to Niroj for helping
What you want to do is "compressing" the JSON input to YAML with references for those mappings that
have exactly the same key-value pairs. In order to achieve that you need to be able to find
such matching mappings and one way to do that is by creating a lookup table based on
the string representation of the mapping after sorting the keys.
Assuming this JSON input in input.json:
{
"en": {
"models": {
"errors": {
"name": "name not found",
"url": "bad url"
}
},
"user": {
"errors": {
"name": "name not found",
"url": "bad url"
}
},
"photo": {
"errors": {
"name": "name not found",
"url": "bad url"
}
}
}
}
You can convert it with this Python script to get:
import json
import sys
from pathlib import Path
import ruamel.yaml
in_file = Path('input.json')
def optmap(d, mappings=None):
if mappings is None:
mappings = {}
if isinstance(d, dict):
for k in d:
v = d[k]
sv = repr(v)
ref = mappings.get(sv)
if ref is not None:
d[k] = ref
else:
mappings[sv] = v
optmap(d[k], mappings)
elif isinstance(d, list):
for idx, item in d:
sitem = repr(item)
ref = mappings.get(sitem)
if ref is not None:
d[idx] = sitem
else:
mappings[sitem] = item
optmap(item, mappings)
data = json.load(in_file.open())
optmap(data)
yaml = ruamel.yaml.YAML()
yaml.serializer.ANCHOR_TEMPLATE = u'%d'
yaml.dump(data, sys.stdout)
which gives:
en:
models: &1
errors:
name: name not found
url: bad url
user: *1
photo: *1
The above will also make references to, and traverse, arrays in your JSON.
As you can see your output can be further "compressed" than you though it could be.
I am not fluent enough in JavaScript to have written this answer in that language (without investing too much effort and delivering some ugly code), but the OP obviously understood the intent of optmap() and implemented it in his answer
Sadly there's no solution to convert JSON to YML with references as far as I know, cause there's no such 'references' rule for repeating nodes in JSON. As the spec says, YAML can therefore be viewed as a natural superset of JSON.

How to convert object in array js [duplicate]

This question already has answers here:
Parse JSON in JavaScript? [duplicate]
(16 answers)
Closed 4 years ago.
I very new to programming and I can't find the solution of my issue, can you give me the solution please?
I have this JSON file:
{
"groups": "[{ id: 1, title: 'group 1' }, { id: 2, title: 'group 2' }]"
}
And I need something like this in my js (but i want import my JSON to get array like this) :
const groups = [{ id: 1, title: 'group 1' }, { id: 2, title: 'group 2' }]
I don't know how to do without using jQuery.
I already tried with this:
const json = require('./test.json');
This code returns an object:
It's almost what I want but it didn't work when I use it in my code because I don't want an object but and array like I said above.
How can achieve this?
The value of groups is not valid JSON: string values should be surrounded by double-quote marks, and so should keys. The file with valid JSON in that string would look like this:
{
"groups": "[{ \"id\": 1, \"title\": \"group 1\" }, { \"id\": 2, \"title\": \"group 2\" }]"
}
Of course if you have control over the creation of this file, it would be better to have this value as part of the native JSON content, rather than JSON-in-a-string-inside-JSON. If that's not possible, you will need to correct the quoting in the string yourself, which can be done with a couple of Regular Expression replacements.
/* obj is the object in the JSON file */
var json_str = obj.groups.replace(/'/g,"\"").replace(/([a-z]+)\:/g,"\"$1\":");
var groups = JSON.parse(json_str);
Alternatively, although the string is not valid JSON it is a valid Javascript expression, so if the contents of the file are trustworthy, you can also do it with eval:
var groups = eval(obj.groups);
I just need to fill my array "groups" like that :
[{ id: 1, title: 'group 1' }, { id: 2, title: 'group 2' }]
with a json file and without jquery
Since I didn't notice the "without jQuery" in the original question, here is a new answer:
var request = new XMLHttpRequest();
request.open('GET', './test.json', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var data = JSON.parse(request.responseText);
} else {
// We reached our target server, but it returned an error
}
};
It does two things:
1. Loads the json file
2. Parses the loaded string into a javascript object.
Before you can even do anything with your JSON file, you need to load it. jQuery has a shortcut, which will even automatically parse the JSON-string into a native JS object for you:
$.getJSON('./test.json', function(data) {
console.dir(data);
});
https://api.jquery.com/jquery.getjson/
if you can't edit original text, you need replace ' to " and then did JSON.parse(json.groups);
otherwise you can change a little your json like this:
JSON.parse('[{ "id": 1, "title": "group 1" }, { "id": 2, "title": "group 2" }]')
be careful with " and ' parentheses
{
"key":"string"
}
string with defined with ' parentheses not valid
in JSON keys must be to in "" parentheses
You can parse the object to an array this way:
Object.values(YOUR_OBJECT)
docs: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/values

Writing text to File in Node.JS

I'm new to Node.js. I have a JSON object which looks like the following:
var results = [
{ key: 'Name 1', value: '1' },
{ key: 'Name 2', value: '25%' },
{ key: 'Name 3', value: 'some string' },
...
];
The above object may or may not have different values. Still, I need to get them into a format that looks exactly like the following:
{"Name 1":"1","Name 2":"25%","Name 3":"some string"}
In other words, I'm looping through each key/value pair in results and adding it to a single line. From my understanding this single line approach (with double quotes) is called "JSON Event" syntax. Regardless, I have to print my JSON object out in that way into a text file. If the text file exists, I need to append to it.
I do not know how to append to a text file in Node.js. How do I append to a text file in Node.js?
Thank you!
You can use JSON.stringify to convert a JavaScript object to JSON and fs.appendFile to append the JSON string to a file.
// write all the data to the file
var fs = require('fs');
var str = JSON.stringify(results);
fs.appendFile('file.json', str, function(err) {
if(err) {
console.log('there was an error: ', err);
return;
}
console.log('data was appended to file');
});
If you want to add just one item at a time, just do
// Just pick the first element
var fs = require('fs');
var str = JSON.stringify(results[0]);

Categories