Node.js environment variable with multiple key/values readable by node.js? - node.js

I would like to create a .env file that has a single environment variable that provides multiple key/values readable by node.js.
For instance:
USERNAME=firstname:John,lastname:Doe
Then something like:
require('dotenv').config()
let myEnvVariable = process.env.USERNAME
let firstName = myEnvVariable.firstname
let lastName = myEnvVariable.lastname
console.log(fistName, lastName)
// expected result: John Doe
Is something like this possible? If so, how do I go about it?

It might be easiest if you just put JSON as the environment variable value. Then, you can just get the value of the environment variable and do JSON.parse() on it and have a fully formed Javascript object as the result. Then, you don't have to invent your own format and don't have to write your own parsing code.
In your environment:
USERNAME={"firstname":"John","lastname":"Doe"}
Then, in your code:
const user = JSON.parse(process.env.USERNAME);
console.log(user.firstname);
console.log(user.lastname);
FYI, this is exactly the kind of things JSON was invented for - a text-only standard format for expressing data that can be generated or parsed easily from nearly any language.

I've never heard of anything like that... but you could work defining your own format for the variable so that you can achieve something like that...
Following your example you could work on a parser that would do it...
const USERNAME="firstname:John,lastname:Doe,phone:countryCode:55,phone:number:99999999999";
const parse = str => {
const output = {};
str.split(',').forEach(part => {
const keys = part.split(':');
const value = keys.pop();
let def = output;
keys.forEach((key, idx) => {
if (idx === keys.length - 1) return def[key] = value;
if (!def[key]) def[key] = {};
def = def[key];
});
});
return output;
};
console.log(parse(USERNAME));
I've never heard of anything like that... but you could work parsing out the format that you created yourself...

Related

How to handle response from JSON but started with numbers

how to handle JSON response, I got this response but I don't know how to handle it. I know variable can't started with numbers, so?
let result = [{"1d":{"volume":"22275409068573.73","price_change":"56446.71564507","price_change_pct":"0.0121","volume_change":"-13864857829188.44","volume_change_pct":"-0.3836","market_cap_change":"9216448958327.75","market_cap_change_pct":"0.0121"}}];
How to parsing"1d"?
I try JSON.parse(result[0].1d); but error happened
If you don't want to use ["prop"] to get value, you can change all props that starts with a number like in the example.
Check this link
var json = JSON.stringify(result);
json = json.replace(/,"[0-9]|{"[0-9]/g, function (x) {
return x.substring(0,1)+'"num'+x.substring(2);
});
result = JSON.parse(json);
var whatIwant = result.num1d;
You can't use JSON.parse for JSON object.
If you want to get value of 1d. Try this
result[0]["1d"]

How to read, update and pass variables between functions that are placed in different .js files?

So, I'm working on a discord bot that has a few functions. I'm using node.js and discord.js.
I broke down the code into a few files because it was getting too long, so now I need something to pass global variables between functions and update them each time.
The first approach I tried was through parameters, but then the variables weren't going to change for the other functions.
1.
async function prepare(message, parameters)
{
// Code here
}
For the second approach I tried using a JSON object. To read and update the values I used readFile and writeFile.
The problem was that when writing the JSON object, some datas were lost, because for some reasons the values were simplified, and that created errors afterward. In particular, the value ruined was from a ReactionCollector object.
2.
// Reads external JSON object.
let rawdata = fs.readFileSync('config.json');
let obj = JSON.parse(rawdata);
// do something with obj.
// Writes JSON object.
let data = JSON.stringify(obj);
fs.writeFileSync('config.json', data);
My last attempt was using a different type of writeFile function, that preserved the datas, but it created problems when reading the JSON object multiple times.
3.
// Reads external JSON object.
const readFile = promisify(fs.readFile);
var data = await readFile('../config.json', { encoding: 'utf8' });
let obj = JSON.parse(data);
// Do something.
// Updates JSON object.
fs.writeFile('../config.json', packageJson, { encoding: 'utf8' }, err => {
if (err) throw err;
console.log("Wrote json.");
});
Anyone that could make this code work?
I found that the best and simpler way is to use getter/setter functions for each variable.
This is an example:
var binary_tree = [];
function setBinary_tree(bt)
{
binary_tree = bt;
}
function getBinary_tree()
{
return binary_tree;
}
module.exports.setBinary_tree = setBinary_tree;
And then here it's how the variables are passed into the external file:
const { getBinary_tree, setBinary_tree } = require('./path/variables.js');
var binary_tree = getBinary_tree();
// Do something with the variable.
// At the end, updates the variables.
setBinary_tree(binary_tree);

Update value once write completes in Cloud Function

I'm trying to update one value after a write completes (in a Cloud Function) but it just wont work (I'm sure this is a stupidly simple problem). Code below:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const firebase = require('firebase');
admin.initializeApp(functions.config().firebase);
exports.createMessage = functions.https.onRequest((request, response) => {
const json = JSON.parse(request.query.json); // == "{'start':0, 'end':0}"
json.start = firebase.database.ServerValue.TIMESTAMP;
admin.database().ref('/messages/').push(json).then(snapshot => {
//Here is the problem. Whatever I try here it won't work to retrieve the value.
//So, how to I get the "start" value, which has been written to the DB (TIMESTAMP value)?
var startValue = snapshot.ref.child('start').val();
snapshot.ref.update({ end: (startValue + 85800000) }).then(snapshot2=>{
response.redirect(303, snapshot.ref);
});
});
});
Is the problem that I'm using admin.database()?
This code:
var startValue = snapshot.ref.child('start').val();
doesn't actually retrieve any values. Take a look at the docs for DataSnapshot. Reach into that snapshot directly with child() - you don't need the ref. Maybe this is what you meant?
var startValue = snapshot.child('start').val();
I'm not sure if there's a bug in Firebase or if I'm using it wrong, but if I try to call any method on the snapshot-reference I will only get an error saying: TypeError: snapshot.xxx is not a function where xxx is the function name i try to use (for example: child(...), forEach(...), etc).
However, the following seems to fix the issue with the snapshot:
admin.database().ref('/messages/').push(json).once('value').then(snapshot => {
instead of:
admin.database().ref('/messages/').push(json).then(snapshot => {
My uneducated guess is that the then-promise, for the push-function returns some faulty snapshot since the only thing that seems to work is snapshot.key.
Also, if I'm not mistaken, doesn't my solution make two reads now, instead of one? Since push will write and then (supposedly) read and return the written value and then I read it once more with once(value).
Does anyone has any further insights into this problem?

Closed over value not picked up in Mongoose Map function

I am trying to create a dynamic map function - ie the use an arbitrary field to aggregate on. I thought I would be able to use a closure for this but it does not work - I get an error stating blah is not defined.
My test code -
o.map = (function(){
var blah = 'skill';
var mapIt = function() {
for (var idx = 0; idx < this[blah].length; idx++) {
var key = this.skill[idx];
var val = 1;
emit(key, val);
}
}
return mapIt
})()
Regards,
Sean
So the map function is actually getting sent over the wire via function toString (in source code form) to mongodb for execution inside mongodb itself (not node). Thus, this doesn't work. This is what the scope option is for. Any data you need to supply as context/arguments/scope to the map/reduce job needs to be set in the scope object.
Looks like you have to set scope manually -
o.scope = {'blah': blah};

How to use chrome.storage in a chrome extension using a variable's value as the key name?

I'm trying to use chrome's local storage / sync storage (chrome.storage) for an extension, to store data entries, for many different entries. I can't seem to figure out the correct syntax for it. I only want to simply store the information as strings. I have searched and can't find anything yet that works.
This is what works for me at the moment using the normal localStorage technique:
var imageName = "Red Cat 5";
var myDescription = "A nice kitty";
localStorage.setItem (imageName, myDescription);
console.log(localStorage[imageName]);
This works and lets me set the key from an existing variable.
How can I do it using chrome.storage.local.set?
I have been trying this without any success:
var imageName = "Red Cat 5";
var myDescription = "A nice kitty";
chrome.storage.local.set({imageName: myDescription}, function()
{console.log('success?');});
chrome.storage.local.set({imageName: myDescription}, function()
{chrome.storage.local.get(imageName, function(r){console.log(r.imageName);});});
Any help is much appreciated. Thanks!
----- UPDATE BELOW -----
Thanks for the explanation with the code. I hope it helps anyone else. There seems to be little information available on doing this! Your answer helped me come up with this:
var nameOne = "al";
var nameTwo = "bob";
var nameThree = "carl";
var nameFour = "dan";
var dataObj = {};
dataObj[nameOne] = nameTwo;
dataObj[nameThree] = nameFour;
storage.set(dataObj);
storage.get(dataObj, function(result)
{
console.log(result[nameOne]);
console.log(result[nameThree]);
});
Use a named object, not an anonymous object, and set a member variable using square brackets:
var dataObj = {};
dataObj[imageName] = myDescription;
chrome.storage.local.set(dataObj, function() { /*...*/ });
It's not the most elegant looking code, but it's the only way to do it.
In ES6, a slightly shorter approach is to use an object literal with a dynamic property name:
chrome.storage.local.set({
[imageName]: myDescription
}, function() { /*...*/ });
the set method accepts object items, and an optional callback, the get accepts optional string or array or object keys and if you passed the first argument, you got to pass the second argument as well.
Example:
// To set
chrome.storage.local.set({'testKey':'Test Value'});
// To get
chrome.storage.local.get('testKey', function(data){
console.log(data);
// logs out "Object {testKey: "Test Value"}"
})

Resources