I am trying to fetch data from the JSON object by using Object.values
so my JSON looks like this
const jsonValue=
[
{
files:{
title:{
"en": "test"
}
,
description:{
"en": "dummy description"
}
}
},
{
files:{
title:{
"eu": "without description"
}
}
},
];
jsonValue.map((data)=>{
const des =Object.values(Object.values(data)[0]?.description)?? "";
console.log(...des)
})
I am trying to fetch the description value and if the description key is not present then it should return a blank space
I am using Object.values because en, and eu values get changed every time so to overcome this I am using Object.values
but it showing me an error cannot convert undefined.
My expected output is I want to fetch the description value if it presents inside the JSON and return a blank space if it is not present in JSON
Your solution is almost correct and I just did a small modification at the end to make it work as per the requirement.
This is how it works
First we will check if description itself is present and retrieve its key or default it to empty string
Then we will check if key is not empty string and then retrieve the value using the key.
Display the required result.
I just added a bit more console logs to show how each step behaves and these are not needed as part of solution.
Like VLAZ suggested it is always handy to use browser debugger tools to see the failed statements.
const jsonValue=
[
{
files:{
title:{
"en": "test"
}
,
description:{
"en": "dummy description"
}
}
},
{
files:{
title:{
"eu": "without description"
}
}
},
];
jsonValue.map((data)=>{
console.log(Object.values(data)[0]?.description);
const desKey = Object.values(data)[0]?.description ?? "";
if(desKey !== ""){
console.log(Object.values(desKey));
const des = Object.values(desKey);
console.log(...des)
}
})
If I understood you correctly, when
const descriptions = jsonValue.map(value =>
value.files.description ?
value.files.description[Object.keys(value.files.title)[0]] :
''
)
console.log(descriptions)
will print ["dummy description", ""] and should do the trock
Related
I'm currently working with react to read and display the elements given in a json file.
As far as this, everything works fine. Now I want to display a text in a label of a checkbox which should also be able to contain links without turning the whole label in a link.
To do this I made this json structure:
"labels": [
"Text without a link",
{
"url": "google.de",
"label": "Link text"
}
]
And to display these side by side I'm mapping over the json Array "labels"
labels: Array<Object>;
labels.map(el => {
if (isString(el))
return el;
else
return <Link href={el['url']} color="inherit">{el['label']}</Link>
})
But I can't access el['url'] or el['label'].
It throws:
"Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'Object'."
Probably I'm just overseeing something unbelievable simple. Help would be nice!
Cheers,
m3_
Try this:
return <Link href={el.url} color="inherit">{el.label}</Link>
Try this
var data = {
"labels": [
"Text without a link", {
"url": "google.de",
"label": "Link text"
}
]
}
const links = data.labels.map(item => {
if(isString(item)) {
return item
}
const { url, label } = item
return <Link href={ url } color="inherit">{ label }</Link>
})
"labels": [
"Text without a link",
{
"url": "google.de",
"label": "Link text"
}
]
here, labels is an array which has values of type string and object. For strings it wont have url and label properties. So while parsing every value using map function, you have to check the type of value is object or not. If it is an object then only check url and label for it.
I am trying to get a value from the nested JSON data below. Specifically, the payments captures id value 0TA12948FV40723B is the value I need.
I try using the following codes to retrieve the value.
details.purchase_units.payments.captures.id
details.purchase_units.payments[0].captures.id
But I keep getting a console.log Error: "Order could not be captured"
JSON DATA
{
"create_time":"2019-02-19T05:06:52Z",
"update_time":"2019-02-19T05:06:52Z",
"id":"3HB96413YD922272B",
"intent":"CAPTURE",
"status":"COMPLETED",
"payer":{
"email_address":"a#yandex.com",
"payer_id":"WEJUPTK4U53E9",
"address":{
"address_line_1":"1 Main St",
"admin_area_2":"San Jose",
"admin_area_1":"CA",
"postal_code":"95131",
"country_code":"US"
},
"name":{
"given_name":"a",
"surname":"som"
},
"phone":{
"phone_number":{
"national_number":"408-214-8270"
}
}
},
"purchase_units":[{
"reference_id":"default",
"amount":{
"value":"1.01",
"currency_code":"USD"
},
"payee":{
"email_address":"gr-facilitator#yandex.com",
"merchant_id":"MSOIGVMKKWAMA"
},
"shipping":{
"name":{
"full_name":"Mr T"
},
"address":{
"address_line_1":"1234 Main St.",
"address_line_2":"Unit 1",
"admin_area_2":"Chicago",
"admin_area_1":"IL",
"postal_code":"60652","country_code":"US"
}
},
"payments":{
"captures":[{
"status":"COMPLETED",
"id":"0TA12948FV40723B",
"final_capture":true,
"create_time":"2019-02-20T05:06:52Z",
"update_time":"2019-02-20T05:06:52Z",
"amount":{
"value":"1.01","currency_code":"USD"
},
"seller_protection":{
"status":"ELIGIBLE",
"dispute_categories":[
"ITEM_NOT_RECEIVED",
"UNAUTHORIZED_TRANSACTION"
]}
}
]}
}]
}
Since purchase_units and captures are arrays:
details.purchase_units[0].payments.captures[0].id
captures key have objects in side an array. so you can't simply fetch like
details.purchase_units.payments[0].captures.id
you have to give the position of the captures or loop the array only you can do parsing
details.purchase_units.payments[0].captures[0].id
If you add your json as object using the chrome console you will be able to do what I did in in the image below. purchase_unit is an array so you need to access it using the index.
In case if you want to capture all the IDs in an array, you can use wild card:
details.purchase_units[*].payments.captures[*].id
This will parse complete payload for specified path and collect all the IDs in an array.
I have an array of javascript object that looks like the following.
jsObjFromCsv =
[
{
"J251525" : {
"APPROVER" : "TOM#MAIL.COM",
"JOB DESCRIPTION " : "CLEAN THE HOUSE",
"JOB NUMBER" : "J251525"
}
}, {
"J512912" : {
"APPROVER" : "JAMES#MAIL.COM",
"JOB DESCRIPTION " : "BRUSH HORSE",
"JOB NUMBER" : "J512912"
}
}, {
"J5-512" : {
"APPROVER" : "HARRY#MAIL.COM",
"JOB DESCRIPTION " : "WASH CAR",
"JOB NUMBER" : "J5-512"
}
}
]
However, when I save to firebase using the following code it looks like this
saveJobToFirebase(jobs: Array<Object>) {
const jobCodesRef = this.af.database.list('/jobCodes/' + this.currentUser.company)
return jobCodesRef.push(jobs);
}
I want to get rid of the 0,1,2 such that I can query end point like
jobCodes/Company1/-Kc8Q5Wuq4M91puQ_70J/J251525
-----------------My Attempt--------------
I have thought of a way that works but it does not seem to be good as explained at the end of this.
So to achieve what I wanted, I firstly change my object array to be the following
[
{
"APPROVER" : "TOM#MAIL.COM",
"JOB DESCRIPTION " : "CLEAN THE HOUSE",
"JOB NUMBER" : "J251525"
}, {
"APPROVER" : "JAMES#MAIL.COM",
"JOB DESCRIPTION " : "BRUSH HORSE",
"JOB NUMBER" : "J512912"
}, {
"APPROVER" : "HARRY#MAIL.COM",
"JOB DESCRIPTION " : "WASH CAR",
"JOB NUMBER" : "J5-512"
}
]
Then I loop through each of the object and grab a job number to get the end point and directly "SET" it to firebase with the following code
saveJobToFirebase(jobs: Array<Object>) {
// previous code
// const jobCodesRef = this.af.database.list('/jobCodes/' + this.currentUser.company)
// return jobCodesRef.push(jobs);
// bad attempt?
for (let job of jobs) {
const jobCodesRef = this.af.database.object('/jobCodes/' + this.currentUser.company + '/' + job['JOB NUMBER']).set(job);
}
}
And this gives me the result that I wanted.
However, there are two big problems with this method
my saveJobToFirebase no longer returns a thenableReference for me to call .then at my Component. This means that I would have no way to track whether or not the action succeeded
I dont know if updating firebase with for loop is a good idea? What if this JSON object has 2000 entries... I would be hammering the end point if I call it inside a for loop. It would be better if I can "push" it so that everything goes in with one request right?
The 0, 1, 2, etc are created because you're saving an array of objects. See this blog post about arrays in Firebase for more on why this behavior exists and why Firebase recommends against storing arrays.
Calling push() will generate a so-called push ID, a value that Firebase guarantees to be unique. But since your jobs already have their own ID, this isn't needed either.
The structure you want to save, seems better: the objects each have a usable key. You could save this object with:
jsObjFromCsv = {
"J251525" : {
"APPROVER" : "TOM#MAIL.COM",
"JOB DESCRIPTION " : "CLEAN THE HOUSE",
"JOB NUMBER" : "J251525"
},
"J512912" : {
"APPROVER" : "JAMES#MAIL.COM",
"JOB DESCRIPTION " : "BRUSH HORSE",
"JOB NUMBER" : "J512912"
},
"J5-512" : {
"APPROVER" : "HARRY#MAIL.COM",
"JOB DESCRIPTION " : "WASH CAR",
"JOB NUMBER" : "J5-512"
}
};
If you watch carefully, you'll see that I've removed the array and the outermost level of objects.
Now you can save this object with:
const jobCodesRef = this.af.database.list('/jobCodes/' + this.currentUser.company)
jobCodesRef.update(jsObjFromCsv);
The return values from update() is thennable, so you can continue when the action has completed (or failed).
For anyone interested, try to transform your array of objects to an object, with just a few lines of reduce
const arrayToObject = (array) =>
array.reduce((obj, item) => {
obj[item.id] = item
return obj
}, {})
const jsObjFromCsv_OBJ = arrayToObject(jsObjFromCsv)
I had similar problem but in node and no answers proved sufficient. I know your code is different but the principle is the same. Hopefully this helps someone in the future. First Firebase can save data in different ways like push or set. Push when using arrays with square brackets automatically adds in those numbers such as 0, 1, 2 so that say two people post on a blog at the same time they don't overwrite each other. Set ignores this and overwrites everything at the path to save the data as you have specified.
In my case I was adding json objects to an array with .push and getting the 0, 1, 2 and I wanted names instead of 0, 1, 2 so I basically just switched the array with an object and instead of using .push I set objects inside the one big object. To illustrate this:
What I used first:
var array = [];
jsonobject={
title:'title'
}
array.push(jsonobject);
//then I used push to firebase that array in an advanced method
The fix:
var mybigjson = {};
var nameiwantinsteadofnumbers = [insert your changing variable for each jsonobject here]
jsonobject={
title:'title'
}
mybigjson[nameiwantinsteadofnumbers]=jsonobject
//then I used push to firebase that object in an advanced method
process.env.ENVIRONMENT = dev2
Input JSON:
{
"base": {
"product1" : "dev1.awesomeproduct1.com",
"product2" : "dev1.awesomeproduct2.com"
}
}
Output JSON:
Based on the process.env.ENVIRONMENT the product urls should be updated dynamically
{
"base": {
"product1" : "dev2.awesomeproduct1.com",
"product2" : "dev2.awesomeproduct2.com"
}
}
Do I correctly understand that you want to replace the part of the domain names up to the dot with your process.env.ENVIRONMENT variable?
Then the following code should work:
for (key in myJSON.base) {
myJSON.base[key] = myJSON.base[key].replace(/^[^.]+/, process.env.ENVIRONMENT);
}
Obviously, you will need to amend it if there are other fields than product<n> in the base object, or if you need to do a more complex replacement.
I have a network array like the following way
"network_contents": [
{
"facebook":"contents to all pages",
},
{
"twitter":"twiter contents",
},
{
"linkedin":"linked in contents",
}
]
I would like to add some keys to that array bases on its content. If it is facebook the key should be facebook, if it is twitter key should be twitter. But not sure how to do it.
My requirement is to access network array contents, but it may or may not content these facebook, twitter, linked in values. I need to access its values. When i assign a key value will be easy to fetch its contents. So i tried this way to loop through the array
message.network_contents.forEach( function (nwContent) {
if(nwContent.twitter) {
console.log('nw content', nwContent.twitter);
}
})
can i create an array in this foreach loop like the following way.
{
"data": [
{
"facebook": {
"facebook": "facebook content"
},
"twitter": {
"twitter": "twitter content"
}
}
]
}
Your help is much appreciated thanks
Implementation of what I said in the comment:
var oldsies = stuff.network_contents;
var newsies = stuff.network_contents = {};
oldsies.forEach(function(network) {
var name = Object.keys(network)[0];
newsies[name] = network;
});
You gave an example of a JS object and not a dictionary and therefore cant add key-values.
You need something like this:
var network_contents = [];
network_contents["facebook"] = {config1: {name:"config1", value:"value1"}};
network_contents["twitter"] = {config2: {name:"config2", value:"value2"}};
example:
network_contents["facebook"].config1.value; // will return "value1"
You can covert your object to a dictionary easily.