JS/Node: Updating a JSON file with the square brackets - javascript

My application needs to write the new users who sign up in to a JSON file, so that later I send this file to users.
What I want is something like:
[
{"username": "A"},
{"username": "B"},
{"username": "C"}
]
When a new user "D" signs up, NodeJS will update the file as:
[
{"username": "A"},
{"username": "B"},
{"username": "C"},
{"username": "D"}
]
However I'm having problems to implement this because although I can 'append' to the file, I cannot write a user name just before the closing ']'.
I tried to do without square brackets and JSON.parse(arayFromFileRead) but it gives me an
'unexpected token {'
error.
Could somebody help with either:
Writing to the file, one line before the last line. That is, the line before the closing squire bracket.
Reading a file as a JSON object without the enclosing square brackets.
Thank you.

In order to write proper JSON (and be able to parse it as such with JSON.parse), you need to have commas between objects inside an array.
[
{"username": "A"},
{"username": "B"},
{"username": "C"}
]

Checkout this example:
var fs = require('fs');
function addUser(user, callback) {
var usersFile = './users.json';
fs.readFile(usersFile, function(err, users) {
if (err) {
return (callback)? callback(err) : console.error(err);
}
users = (users)? JSON.parse(users) : [];
users.push(user);
fs.writeFile(usersFile, JSON.stringify(users), function(err, result){
(callback)? callback(err, result) : console.error(err);
});
});
}
addUser({username: 'D', password: 'blablabla'});
logic:
to have one users.json file where we'll keep all user data serialized by JSON.stringify() function.
to do so You've to read whole file to variable, parse it, push new record to variable, serialize (stringify) and save it back to file
benefits:
there is no benefit! when Your file will be bigger You'll waste more memory and CPU to read it, push, serialize, write back. also Your file will be locked during read/write
SO BETTER TO DO THIS:
1) create users folder
2) make Your code like this:
var fs = require('fs');
var path = require('path');
var md5 = require('md5');
var usersDir = './users';
function addUser(user, callback) {
var userFile = path.join(usersDir, md5(user.username)+'.json');
fs.writeFile(userFile, JSON.stringify(user), function(err, result){
(callback)? callback(err, result) : console.error(err);
});
}
addUser({username: 'D', password: 'blablabla'});
logic: You have users folder where You keep users records "file per user" way
benefits:
when You've 1 file (users.json) You're having issue of parallel accessing same file.
but when You files are separate, so filesystem itself acts as database, where json file is row and content is document.

Related

How to format JSON file data by filtering only info needed?

I recently exported all my user data from Firebase and now I want to format the JSON file to filter only the relevant field I need for my data model.
The file I got on Firebase is currently stored like this:
{
"Users": {
"00uniqueuserid3": {
"1UserName": "Pusername",
"2Password": "password",
"3Email": "email#gmail.com",
"4City": "dubai"
}
}
}
The issue is that the JSON file got over 5,000 users and I cannot get possibly manual format them how I want them. Is there any Javascript script or tool I can use to reformat all the data in the file, I would like to format them as such:
{"id": uniqueid , "name": name, "email": email, "city": city}
You can create a new NodeJS project (npm init -y) and install mongodb. Then read the JSON file and modify the format using JS:
const mongodb = require("mongodb")
const exportedData = require("./myFirebaseExport.json");
const db = "" // <-- Mongo Client
const data = Object.values(exportedData.Users);
const parsedData = data.map((d) => {
// modify the data array as required;
return {
name: d.username, // replace with your field names
email: d.Email,
}
})
await db.collection("users").insertMany(parsedData);

Key from one Json file to value of another Json file using node/Javascript

I tried and searched to make a JSON file who's keys are data in other JSON file
for eg:
admin in user.json is the key but it will act like value inside the Schema.json file
same other keys which are present inside the user.json file will act like value inside Schema.json file.
suppose I have user.json name Json file and in user.json file my keys are admin, id, fname, lname, etc
I want to make a another json with schema.json name where the keys which are present inside user.json are value of those schema.json
user.json
"addmin":{
"id":"01",
"fname":"tom",
"lname":"jerry",
"graduation":"PG",
"address":"NYC",
"job":"yes",
"dreams":"travelling world"
...
...
...
}
image have a clear view what i want to achieve
I don't know how this gonna be done I tried by doing this but still not happening am getting the value from the file if I get key I can store it in Schema.json
fs.readFile(
"user.json",
function (err, data) {
if (err) throw err;
obj = JSON.parse(data);
console.log(obj.admin.id);
}
);
I'm not sure you've defined the problem well enough yet, to be able to come up with a full solution. But it might involve using the the Object.keys() function (documented at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) to help you parse your JSON object. To get you started, take a look at this:
fs.readFile(
"user.json",
function (err, data) {
if (err) throw err;
obj = JSON.parse(data);
var schema = Object.keys(obj).map(function (key) {
return {
uid: key,
schema: Object.keys(obj[key]).map(function (itemKey) {
return {
uid: itemKey
}
}),
};
};
}
);

Node.js - create dynamic json object and write to .json file

I am new to JS ecosystem and a requirement is to create a json object dynamically at run time and to write it to .
{
"prerequisite": [
{
"url1": "",
"step1": {},
"step2": {}
}
],
"PF": [
{},
{}
]
}
I tried using new Object() but not sure how to build this complex one (to my extent its complex ).
For writing it to file i understand using FS we can achieve it.
Need support on building this json object at run time
I guess you'd like to do something like this. I'm not sure how you want to make it dynamic, but if you have a json object, you can always add to it like this: json_obj.something = "anything"
And it save (overwrite) every time when it runs. Save this code to a file (like filename.js) and run it. (node filename.js)
Oh and must be stringify the json since the FS "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView
const fs = require("fs")
const FILE = "./json_obj.json"
const json_obj = {
prerequisite: [
{
url1: "",
step1: {},
step2: {},
},
],
PF: [{}, {}],
}
fs.writeFile(FILE, JSON.stringify(json_obj), (err) => {
if (err) {
console.error(err)
return
}
})

webauthn authentication javascript formatting assistance

I have been trying to figure out how to do 2fa with webauthn and I have the registration part working. The details are really poorly documented, especially all of the encoding payloads in javascript. I am able to register a device to a user, but I am not able to authenticate with that device. For reference, I'm using these resources:
https://github.com/cedarcode/webauthn-ruby
https://www.passwordless.dev/js/mfa.register.js
And specifically, for authentication, I'm trying to mimic this js functionality:
https://www.passwordless.dev/js/mfa.register.js
In my user model, I have a webauthn_id, and several u2f devices, each of which has a public_key and a webauthn_id.
In my Rails app, I do:
options = WebAuthn::Credential.options_for_get(allow: :webauthn_id)
session[:webauthn_options] = options
In my javascript, I try to mimic the js file above and I do (this is embedded ruby):
options = <%= raw #options.as_json.to_json %>
options.challenge = WebAuthnHelpers.coerceToArrayBuffer(options.challenge);
options.allowCredentials = options.allowCredentials.map((c) => {
c.id = WebAuthnHelpers.coerceToArrayBuffer(c.id);
return c;
});
navigator.credentials.get({ "publicKey": options }).then(function (credentialInfoAssertion)
{
// send assertion response back to the server
// to proceed with the control of the credential
alert('here');
}).catch(function (err)
{
debugger
console.error(err); /* THIS IS WHERE THE ERROR IS THROWN */
});
The problem is, I cannot get past navigator.credentials.get, I get this error in the javascript console:
TypeError: CredentialsContainer.get: Element of 'allowCredentials' member of PublicKeyCredentialRequestOptions can't be converted to a dictionary
options at the time navigator.credentials.get is called looks like this:
I've tried every which way to convert my db-stored user and device variables into javascript properly encoded and parsed variables but cannot seem to get it to work. Anything obvious about what I'm doing wrong?
Thanks for any help,
Kevin
UPDATE -
Adding options json generated by the server:
"{\"challenge\":\"SSDYi4I7kRWt5wc5KjuAvgJ3dsQhjy7IPOJ0hvR5tMg\",\"timeout\":120000,\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"OUckfxGNLGGASUfGiX-1_8FzehlXh3fKvJ98tm59mVukJkKb_CGk1avnorL4sQQASVO9aGqmgn01jf629Jt0Z0SmBpDKd9sL1T5Z9loDrkLTTCIzrIRqhwPC6yrkfBFi\"},{\"type\":\"public-key\",\"id\":\"Fj5T-WPmEMTz139mY-Vo0DTfsNmjwy_mUx6jn5rUEPx-LsY51mxNYidprJ39_cHeAOieg-W12X47iJm42K0Tsixj4_Fl6KjdgYoxQtEYsNF-LPhwtoKwYsy1hZgVojp3\"}]}"
This is an example of the serialised JSON data returned by our implementation:
{
"challenge": "MQ1S8MBSU0M2kiJqJD8wnQ",
"timeout": 60000,
"rpId": "identity.acme.com",
"allowCredentials": [
{
"type": "public-key",
"id": "k5Ti8dLdko1GANsBT-_NZ5L_-8j_8TnoNOYe8mUcs4o",
"transports": [
"internal"
]
},
{
"type": "public-key",
"id": "LAqkKEO99XPCQ7fsUa3stz7K76A_mE5dQwX4S3QS6jdbI9ttSn9Hu37BA31JUGXqgyhTtskL5obe6uZxitbIfA",
"transports": [
"usb"
]
},
{
"type": "public-key",
"id": "nbN3S08Wv2GElRsW9AmK70J1INEpwIywQcOl6rp_DWLm4mcQiH96TmAXSrZRHciZBENVB9rJdE94HPHbeVjtZg",
"transports": [
"usb"
]
}
],
"userVerification": "discouraged",
"extensions": {
"txAuthSimple": "Sign in to your ACME account",
"exts": true,
"uvi": true,
"loc": true,
"uvm": true
}
}
This is parsed to an object and the code used to coerce those base64url encoded values is:
credentialRequestOptions.challenge = WebAuthnHelpers.coerceToArrayBuffer(credentialRequestOptions.challenge);
credentialRequestOptions.allowCredentials = credentialRequestOptions.allowCredentials.map((c) => {
c.id = WebAuthnHelpers.coerceToArrayBuffer(c.id);
return c;
});
Hope that helps. The JSON data is retreived via a fetch() call and the byte[] fields are encoded as base64url on the serverside.

How to store objects in a Json file

I would like to store accounts in a json file.
Something like : accounts{[user: user1, email: email1], [user: user2. email: email2]}
Javascript file
Accounts = {
Nickname: form.getElementsByTagName('input')[0].value,
Email: form.getElementsByTagName('input')[3].value
};
var json = JSON.stringify(Accounts);
fs.appendFile('Accounts.json', json, function(err){});
When I add a second user this code make a new object and it looks like.
Json file
{"NickName": "user1", "Email": "Email1"}{"NickName": "user2", "Email": "Email2"}
Then, when I try to read the file and parse it I receive an unexpected error {
I think the Json file should look like
{
{"Name":"value"},
{"Name2":"value2"}
}
I fix the issue.
Here the solution with a mix of Michael Brune's solution.
// Read accounts.json
const Accounts = fs.readFileSync('Accounts.json', 'utf-8');
// Check if json file is empty
if(Accounts.length !== 0){
var ParsedAccounts = JSON.parse(Accounts);
}
else{
ParsedAccounts = [];
}
ParsedAccounts.push(Account);
const NewData = JSON.stringify(ParsedAccounts, null, 4);
// Write new data to accounts.json
fs.writeFileSync('Accounts.json', NewData);
Basically, I push the new data in ParsedAccounts then I write it in the json file.
Maybe there is another way, but if your file is pretty small, then try like this:
Accounts.json:
{
"other": "other data"
}
index.js
const fileData = fs.readFileSync('Accounts.json');
let parsedFileData
try {
parsedFileData = JSON.parse(fileData);
} catch (error) {
if (error instanceof SyntaxError) {
// Create empty object to append to since parse was not a success
parsedFileData = {};
// Create backup of old, possible corrupt file
fs.writeFileSync('Accounts.backup.json', fileData);
}
}
const newFileData = JSON.stringify({
...parsedFileData,
...newDataToAppend,
}, null, 4);
fs.writeFileSync('Accounts.json', newFileData);
First you can parse the file.
Assign new and old data to a object.
Then convert that to srting JSON.Stringify
The null and 4 are to write a nice pretty file
Then write it to the file directly.

Categories