Getting the property of an associative array given as an escaped string - node.js

I have an array that looks like this:
[{"x": "someValue",
"y" : "{\"iWantThisValue\":\"a\", \"otherVal2\":\"b\"}"}]
I want to get the value of "iWantThisValue". On the view, I have #{JSON.parse(myArray.y)}. If I try to put something like .iWantThisValue after it, nothing is printed out. Is this a correct step to getting it? Where do I go from here?

You're pretty close, but you need to subscript the array.
var myArray = [
{
"x": "someValue",
"y" : "{\"iWantThisValue\":\"a\", \"otherVal2\":\"b\"}"
}
];
console.log( JSON.parse( myArray[0].y ).iWantThisValue );
Logs a.
Of course in real code, you probably wouldn't just be doing [0] to access an array element, but would probably be looping through the array? Either way, you'd still need to use myArray[index] where index is 0 in this example.
Also, in the interest of clarity, JavaScript does not have anything called an "associative array". It has arrays and it has objects. In your example, myArray is an array of one element. That element is an object which has x and y properties.

Related

How can I get the multiple subchild objects from json using nodejs?

I am trying to fetch the specifice object from my json files. For now I can fetch any tag instead of the "p" tag from it. you can please have look at the screenshot I have attached.
Click to open the json file
this is how I'm trying to fetch p tag:
'use strict';
const fs = require('fs');
var data = JSON.parse(fs.readFileSync('./me.json'));
data.Document.Decision.forEach(x => {
console.log(x.Texte_Integral.p);
});
This is a weird way of organizing your block, I recommend rewriting/reorganizing the JSON so it is more easily accessible.
There are a few things you have to know before this answer makes sense:
Array indexes
[] resembles an array, you can access each index by doing array[index], for example:
let arr = ['zero', 'one', 'two'];
console.log(arr[0]); //expected output: 'zero'
Bracket Notation
In JavaScript, there are two ways to access a variable's value, either by dot notation or bracket notation. As far as I know, the only differences these have are just the ability to use dynamic input and characters you can't usually use inside a variable's name, for example:
let obj = {
var1: "this is variable1",
var2: {
var3: "this is variable3 inside variable2"
}
}
console.log(obj.var1) //expected output: "this is variable1"
console.log(obj[`var1`]) // expected output: "this is variable1"
console.log(obj.var2.var3) //expected output: "this is variable3 inside variable2"
console.log(obj[`var2`].var3) // expected output: "this is variable3 inside variable2"
console.log(obj[`var2`]["var3"]) // expected output: "this is variable3 inside variable2"
Bracket notation also works inside objects, thus why the variable names inside as a string, like "Document", works.
let obj2 = {
"var1": 1,
["var2"]: 2,
var3: 3
};
console.log(obj2["var1"]) // expected output: 1
// console.log(obj2"var1") is INVALID and does not work
console.log(obj2["var2"]) // expected output: 2
console.log(obj2.var3) // expected output: 3
Coming to the solution
data.Document.Decision.forEach(x => {
console.log(x.Texte_Integral[0].p)
});
This returns ["ASDFDSFDSFSD"], if we wanted to use it as a string and not an array (remember the brackets) then we would access the first index of the array. This would be done by adding [0] at the end.
❕ Solution
data.Document.Decision.forEach(x => {
console.log(x.Texte_Integral[0].p[0])
});
Future Information
About stackoverflow, next time, please share code via code blocks and not screenshots. Thank you for coming to ask your question, we just want it to be easier for us to both understand and access the code! I had to type the whole thing out myself, which could've been easily avoided by just copy/paste-ing the code. If you don't know how to do certain things in the textbox, see the formatting help page.

NodeJS why is object[0] returning '{' instead of the first property from this json object?

So I have to go through a bunch of code to get some data from an iframe. the iframe has a lot of data but in there is an object called '_name'. the first key of name is 'extension_id' and its value is a big long string. the json object is enclosed in apostrophes. I have tried removing the apostrophes but still instead of 'extension_id_output' I get a single curly bracket. the json object looks something like this
Frame {
...
...
_name: '{"extension_id":"a big huge string that I need"} "a bunch of other stuff":"this is a valid json object as confirmed by jsonlint", "globalOptions":{"crev":"1.2.50"}}}'
}
it's a whole big ugly paragraph but I really just need the extension_id. so this is the code I'm currently using after attempt 100 or whatever.
var frames = await page.frames();
// I'm using puppeteer for this part but I don't think that's relevant overall.
var thing = frames[1]._name;
console.log(frames[1])
// console.log(thing)
thing.replace(/'/g, '"')
// this is to remove the apostrophes from the outside of the object. I thought that would change things before. it does not. still outputs a single {
JSON.parse(thing)
console.log(thing[0])
instead of getting a big huge string that I need or whatever is written in extension_id. I get a {. that's it. I think that is because the whole object starts with a curly bracket. this is confirmed to me because console.log(thing[2]) prints e. so what's going on? jsonlint says this is a valid json object but maybe it's just a big string and I should be doing some kind of split to grab whaat's between the first : and the first ,. I'm really not sure.
For two reasons:
object[0] doesn't return the value an object's "first property", it returns the value of the property with the name "0", if any (there probably isn't in your object); and
Because it's JSON, and when you're dealing with JSON in JavaScript code, you are by definition dealing with a string. (More here.) If you want to deal with the object that the JSON describes, parse it.
Here's an example of parsing it and getting the value of the extension_id property from it:
const parsed = JSON.parse(frames[1]._name);
console.log(parsed.extension_id); // The ID

Updating ArangoDB sub document

I am currently evaluating whether ArangoDB can be a future alternative for us. As a part of this evaluation I am porting code that talks to our current NoSQL db into code that speaks ArangoDB. While it has been a fairly smooth ride so far, I am having surprisingly difficult to wrap my head around on how to update sub documents. Assuming we have something like this:
{
"_key": "12345",
"subdoc": {
"0": {
"num_sold": 6,
"other_attribute": "important"
},
"1": {
"num_sold": 4,
"other_attribute": "important"
}
}
}
What I would like to accomplish now it to atomically increase num_sold.
A very first naive approach was of course to try something similar to:
FOR d in ##collection
FILTER d._key == "12345"
UPDATE d WITH { subdoc.0.num_sold : subdoc.0.num_sold + 1 } IN ##collection
RETURN d
(Spoiler alert for the copy-pasters out there: move on. This snippet will just make your life miserable.)
This obviously didn't work and most likely for more than one reason. Arango does not seem to like me referencing the attribute using dot notation, the attribute starting with a number ("0") might also be an issue etc. While having found an example here it seemed both a bit complicated and convoluted for what I am trying to do. There is also another discussion here that is close to what I would like to do. However, the proposed solution in that discussion uses the keyword OLD that creates an error in my case as well as the code replacing all keys in "0".
1) What is the best way to atomically increase num_sold?
2) When is an operation atomic? (Trying to stay away from transactions as long as possible)
3) When can the dot notation be used and when can it not be used?
4) Can I bind parameters to an attribute? For instance letting some #attribute be subdoc.0.num_sold?
Thanks!
ArangoDB can't parse the query if you use numbers in the dot notation.
However there is an easy way - simply use brackets instead of the dot notation as you did.
Example - not working:
db._query(`
LET testdoc = {subdoc: {"0": "abc"}}
RETURN testdoc.subdoc.0`)
ArangoError 1501: syntax error, unexpected integer number,
expecting identifier or bind parameter near '0' at
position 1:60 (while parsing)
Example - fixed:
db._query(`
LET testdoc = {subdoc: {"0": "abc"}}
RETURN testdoc.subdoc.[0]`)
[
"abc"
]
Using bind variables - not working:
db._query(`
LET testdoc = {subdoc: {"0": "abc"}}
RETURN testdoc.subdoc.#bv`, {bv: 0})
ArangoError 1501: syntax error, unexpected integer number,
expecting identifier or bind parameter near '0' at
position 1:60 (while parsing)
Using bind variables - fixed:
db._query(`
LET testdoc = {subdoc: {"0": "abc"}}
RETURN testdoc.subdoc.[#bv]`, {bv:0})
[
"abc"
]

Convert a string to array in velocity

I have a velocity variable, like this:
$cur_record.getFieldValue("SelectRoles", $locale)
that is supposed to be an array. If I print its value, (just by putting $cur_record.getFieldValue("SelectRoles", $locale) in the code) i get:
["Accountant","Cashier"]
now, i want to iterate those 2 values, Accountant and Cashier, but it seems to be a String, not an Array, how can i convert that to an array so I can iterate it?..
I have tried to iterate it, but does not work, like this:
#foreach($bla_role in $cur_record.getFieldValue("SelectRoles", $locale))
$bla_role
#end
Also tried to get the value, as if it were an array, does not work either:
$cur_record.getFieldValue("SelectRoles", $locale).get(0)
I've tried setting it to another variable, like this:
#set($roleval = $cur_record.getFieldValue("SelectRoles", $locale))
$roleval.get(0)
but it does not work, but if i set a string, as the value is printed (the value hard coded), it does work!, like this:
#set($roleval = ["Accountant","Cashier"])
$roleval.get(0)
I dont know if I have to escape something, or I am missing something, can some one help me?
thank you!
You're trying to parse a String array that was previously serialized to String.
The following snippet uses substring, split and replace String methods to parse it.
#set($roleval = '["Accountant","Cashier"]')
#set($rolevalLengthMinusOne = $roleval.length() - 1)
#set($roles = $roleval.substring(1, $rolevalLengthMinusOne).split(","))
#foreach($role in $roles)
<h1>$role.replace('"',"")</h1>
#end
At first I tried to use #evaluate to parse it, but I ended up with these String methods.

groovy - findAll getting only one value

I'm struggling to find examples of findAll with groovy. I've got a very
simple code snippet that gets the property of a node and outputs it's
value. Except I'm only getting the last value when I'm looping through
a series of properties. Is there something I'm doing wrong here, this
seems really simple.
JcrUtils.getChildNodes("footer").findAll{
selectFooterLabel = it.hasProperty("footerLabel") ? it.getProperty("footerLabel").getString() : ""
}
In my jsp I'm just printing the property:
<%=selectFooterLabel%>
Thanks for the help!
findAll returns a List containing all the items in the original list for which the closure returns a Groovy-true value (boolean true, non-empty string/map/collection, non-null anything else). It looks like you probably wanted collect
def footerLabels = JcrUtils.getChildNodes("footer").collect{
it.hasProperty("footerLabel") ? it.getProperty("footerLabel").getString() : ""
}
which will give you a List of the values returned by the closure. If you then want only the subset of those that are not empty you can use findAll() with no closure parameter, which gives you the subset of values from the list that are themselves Groovy-true
def footerLabels = JcrUtils.getChildNodes("footer").collect{
it.hasProperty("footerLabel") ? it.getProperty("footerLabel").getString() : ""
}.findAll()

Resources