This question is purely syntax. I'm trying to insert a generated JSON object into another JSON object.
Let's say my JSON looks like this:
var database =
{
"john": {
"pwd": "somehashrighthere",
"mail": "example#gmail.com"
}
}
This object stores a hash and an email under the users name. Now I want to insert a new user:
var name = "somename";
var pwd = "hash";
var mail = "email#email.net";
If I try to insert this into a json object as by
database.name =
{
"pwd": pwd,
"mail": mail
}
I would expect an output that fills the gaps:
{
"john": {
"pwd": "r1pper",
"mail": "example#gmail.com"
},
"somenamerighthere": {
"pwd": "hash",
"mail": "email#email.net"
}
}
Instead the javascipt takes the expression quite literall:
{
"john": {
"pwd": "r1pper",
"mail": "example#gmail.com"
},
"name": {
"pwd": "pwd",
"mail": "mail"
}
}
I'm quite new to javascript/json and would appreciate if you guys exlain to me how one could dynamically(!) generate json objects and feed them into a bigger data structure. None of the answers I found on SO could solve this problem in a way I could understand. Do I need to make changes to the datastructure, or have I just misunderstood the javascript/node.js syntax. Thanks in advance :)
Edit: I solved the problem quite simply. Turns out javascript actually passes the variables into the json and I was just confused:
{
"john": {
"pwd": "r1pper",
"mail": "example#gmail.com"
},
"name": {
"pwd": "hash",
"mail": "email#email.net"
}
}
Now we just need to pass the name dynamically, which can be solved by treating the JSON, as if it was an array:
database[name]
treats name as a variable.
Edit 2:
The comments below came in while editing. I apologize for that.
you should use database[name] (take the value of name and use as index)
instead of database.name (use the string 'name' as index)
Related
I created a Mongoose schema that allowed me to save a whole JSON object which contains an array of objects (those objects have the _ids I want), but when I try to get one user from router.get express (I'm using findById), it returns null, when I do a get petition getting the whole data (using find() method) it looks like this:
thanks to all of you, English is not my first language, sorry for whatever grammar mistake that I could've made
[
{
"_id": "6384db62827c2f0816944734",
"arrayData": [
{
"description": "KEYCAPS",
"price": "$99.00",
"img": "link,of.the.image",
"_id": "6384db62827c2f0816944735"
},
{
"description": "KEYCAPS",
"price": "$99.00",
"img": "link,of.the.image2",
"_id": "7454db62827c2f0816912345"
}
]
}
]
I've tried other ways of getting the ids, to be honest I've been coding just for a couple of months, I'm a little shy of showing it but I believe this is the code I need to change
router.get('/users/:id', (req, res) => {
const { id } = req.params;
userSchema
.findById(id)
.then((data) => {res.json(data)})
.catch((err) => res.json({message: err}))
})
by the way my request.http enter image description here
enter image description here
Right, so I am trying to wrap my head around editing (appending data) to a JSON file.
The file (users.json) looks like this:
{
"users": {
"id": "0123456789",
"name": "GeirAndersen"
}
}
Now I want to add users to this file, and retain the formatting, which is where I can't seem to get going. I have spent numerous hours now trying, reading, trying again... But no matter what, I can't get the result I want.
In my .js file, I get the data from the json file like this:
const fs = require('fs').promises;
let data = await fs.readFile('./test.json', 'utf-8');
let users = JSON.parse(data);
console.log(JSON.stringify(users.users, null, 2));
This console log shows the contents like it should:
{
"id": "0123456789",
"name": "GeirAndersen"
}
Just to test, I have defined a new user directly in the code, like this:
let newUser = {
"id": '852852852',
"name": 'GeirTrippleAlt'
};
console.log(JSON.stringify(newUser, null, 2));
This console log also shows the data like this:
{
"id": "852852852",
"name": "GeirTrippleAlt"
}
All nice and good this far, BUT now I want to join this last one to users.users and I just can't figure out how to do this correctly. I have tried so many version and iterations, I can't remember them all.
Last tried:
users.users += newUser;
users.users = JSON.parse(JSON.stringify(users.users, null, 2));
console.log(JSON.parse(JSON.stringify(users.users, null, 2)));
console.log(users.users);
Both those console logs the same thing:
[object Object][object Object]
What I want to achieve is: I want to end up with:
{
"users": {
"id": "0123456789",
"name": "GeirAndersen"
},
{
"id": "852852852",
"name": "GeirTrippleAlt"
}
}
When I get this far, I am going to write back to the .json file, but that part isn't an issue.
That's not really a valid data structure, as you're trying to add another object to an object without giving that value a key.
I think what you're really looking for is for 'users' to be an array of users.
{
"users": [
{
"id": "0123456789",
"name": "GeirAndersen"
},
{
"id": "852852852",
"name": "GeirTrippleAlt"
}
]
}
You can easily create an array in JS and the push() new items into your array. You JSON.stringify() that with no issue.
const myValue = {
users: []
};
const newUser = {
'id': '0123456789',
'name': "GeirAndersen'
};
myValue.users.push(newUser);
const strigified = JSON.stringify(myValue);
I'm using Dynamoose to simplify my interactions with DynamoDB in a node.js application. I'm trying to write a query using Dynamoose's Model.query function that will search a table using an index, but it seems like Dynamoose is not including all of the info required to process the query and I'm not sure what I'm doing wrong.
Here's what the schema looks like:
const UserSchema = new dynamoose.Schema({
"user_id": {
"hashKey": true,
"type": String
},
"email": {
"type": String,
"index": {
"global": true,
"name": "email-index"
}
},
"first_name": {
"type": String,
"index": {
"global": true,
"name": "first_name-index"
}
},
"last_name": {
"type": String,
"index": {
"global": true,
"name": "last_name-index"
}
}
)
module.exports = dynamoose.model(config.usersTable, UserSchema)
I'd like to be able to search for users by their email address, so I'm writing a query that looks like this:
Users.query("email").contains(query.email)
.using("email-index")
.all()
.exec()
.then( results => {
res.status(200).json(results)
}).catch( err => {
res.status(500).send("Error searching for users: " + err)
})
I have a global secondary index defined for the email field:
When I try to execute this query, I'm getting the following error:
Error searching for users: ValidationException: Either the KeyConditions or KeyConditionExpression parameter must be specified in the request.
Using the Dynamoose debugging output, I can see that the query winds up looking like this:
aws:dynamodb:query:request - {
"FilterExpression": "contains (#a0, :v0)",
"ExpressionAttributeNames": {
"#a0": "email"
},
"ExpressionAttributeValues": {
":v0": {
"S": "mel"
}
},
"TableName": "user_qa",
"IndexName": "email-index"
}
I note that the actual query sent to DynamoDB does not contain KeyConditions or KeyConditionExpression, as the error message indicates. What am I doing wrong that prevents this query from being written correctly such that it executes the query against the global secondary index I've added for this table?
As it turns out, calls like .contains(text) are used as filters, not query parameters. DynamoDB can't figure out if the text in the index contains the text I'm searching for without looking at every single record, which is a scan, not a query. So it doesn't make sense to try to use .contains(text) in this context, even though it's possible to call it in a chain like the one I constructed. What I ultimately needed to do to make this work is turn my call into a table scan with the .contains(text) filter:
Users.scan({ email: { contains: query.email }}).all().exec().then( ... )
I am not familiar with Dynamoose too much but the following code below will do an update on a record using node.JS and DynamoDB. See the key parameter I have below; by the error message you got it seems you are missing this.
To my knowledge, you must specify a key for an UPDATE request. You can checks the AWS DynamoDB docs to confirm.
var params = {
TableName: table,
Key: {
"id": customerID,
},
UpdateExpression: "set customer_name= :s, customer_address= :p, customer_phone= :u, end_date = :u",
ExpressionAttributeValues: {
":s": customer_name,
":p": customer_address,
":u": customer_phone
},
ReturnValues: "UPDATED_NEW"
};
await docClient.update(params).promise();
Here's my situation, I have a JSON that looks somewhat like this:
{
"items": [{
"type": "condition",
"data": {
"type": "comparison",
"value1": {
"source": "MyType1",
"component": "Attribute1"
},
"value2": {
"source": "MyType2",
"component": "Attribute2"
},
"operator": "gt"
}
},
{
"type": "then",
"data": {
"result": "failed",
"message": "value1 is too high"
}
}
]
}
and would want it to translate to:
if (MyType1.Attribute1 > MyType2.Attribute2) {
result = "failed";
console.log("value1 is too high");
}
Now my problem is, I don't know how I would translate the entries of value1 and value2 to actual code, or rather, how I could access the Object MyType1(maybe through something like getAttribute("MyType1")).
Since I am going to have a whole bunch of sources which each have different components, I cant really write a huge dictionary. Or I would like to avoid it.
The goal is to allow creating if - then - statements via some interactive UI, and I figured it'd be best to save that code as .json files. (Think rule management system).
So, TL,DR, How would I access a Class Attribute this.MyType, if I only have a String MyType to go from? And how would I access the value this.MyType.MyValue, if I get another String MyValue?
Thanks in advance.
Edit:
I'd really like to avoid using eval, for obvious reasons. And if I have to - I guess I would need to create Dictionaries for possible JSON Values, to validate the input?
You need some kind of parser. At first we need some way to store variables and maybe flags:
const variables = {};
var in = false;
Then we go through the code and execute it:
for(const command of items){
switch( command.type ){
case "condition":
//...
case "then":
//...
}
}
To access a variable we can simply do
var current = variables[ identifier ];
To store its the other way round:
variables[ identifier ] = current;
Can you guys teach me on how to use jsoniq to display both of the book name which is robin cruose and tom jones? i've gone through some research but no matter how i do, it's always wrong.
{
"books": {
"reader": {
"Read": {
"book": {
"name": "Robinson Crusoe",
"author": "Daniel Defoe"
}
},
"HaventRead": {
"book": {
"name": " Tom Jones",
"author": "Henry Fielding "
}
},
"_type": "Ken Rawing"
}
}
}
This is how i did in zorba.io and it got lots of error, i am very sure the way i did is totally wrong. Please teach me
for $reader in collection("books"),
$read in collection("books"),
$book in collection ("books")
where $reader.type eq "Ken Rawing"
return $book
Getting some leaf values from a JSON document is done with the navigation syntax, which is the . notation.
It doesn't need a for clause, as iteration is implicit with the ..
Assuming the object is stored in the variable $content, $content.books.reader navigates to the object with the fields Read and HaventRead. Calling jnlib:values() then gets the two objects in there, and then one continues all the way to the name with .book.name.
The query is like so (most of it is actually the input document itself, which is typically stored in a file or a data store instead):
jsoniq version "1.0";
import module namespace jnlib = "http://jsoniq.org/function-library";
(: That's the input document, stored in a global variable :)
declare variable $content := {
"books": {
"reader": {
"Read": {
"book": {
"name": "Robinson Crusoe",
"author": "Daniel Defoe"
}
},
"HaventRead": {
"book": {
"name": " Tom Jones",
"author": "Henry Fielding "
}
},
"_type": "Ken Rawing"
}
}
};
(: That's the query :)
jnlib:values($content.books.reader).book.name
Mind the jsoniq version="1.0";, which activates the native JSONiq parser (the default parser on try.zorba.io is XQuery).
It can also be tested in zorba.io
Note
JSONiq also exists as an extension to XQuery, in which case navigation is done with function calls, as the . is a valid character in XML names. However, it is not recommended to use this unless you have XML to deal with as well.
jnlib:values($content("books")("reader"))("book")("name")