Get object value that has numeric key in react native - javascript

I getting data as object like below:
{
"Version": "AAA",
"Schema" : "AAA",
"Total" : 432234,
....
"Content": {
"1" : {
"1" : {
...
},
"2" : {
...
},
...
}
}
}
How can I get the values from the numeric key in react native?
something like this:
var first_numeric_key = 1;
var second_numeric_key = 2;
aboveObject.Content[first_numeric_key][second_numeric_key];
I tried with the below script but still getting issues.
aboveObject.Content["1"]
TypeError: undefined is not an object (evaluating '_this4.state.contents.content["1"])
What is the best approach for this?

I am not a React Native guy but this seems more like a JavaScript syntax nuance.
You can access object keys as obj['key']
Here, in your case, it will be
aboveObject.Content['1']['2']
Updating answer after OP's edit to the question
const first_numeric_key = 1;
const second_numeric_key = 2;
aboveObject.Content[first_numeric_key.toString()][second_numeric_key.toString()];
EDIT
This is working without convert to the string
aboveObject.Content[first_numeric_key][second_numeric_key]
The issue was the exception handling, since there was some delaying when the app get the data from the fetch() function so the aboveObject was null at the very first time.

Related

Convert JSON String to JSON Object in JavaScript

I understand there are many similar questions exist, however I couldn't find a proper answer.
Consider the Javascript object,
var a = [ { defaultCount:'200' , timeintervals : [{ day:'Weekday', from:'9:00', to:'18:00', count:'100' }, { day:'Weekday', from:'9:00', to:'18:00', count:'100' } ]}];
Now running a[0].defaultCount gives me "200" as expected.
Now the same Javascript object, I am putting inside double quotes.
var b = "[ { defaultCount:'200' , timeintervals : [{ day:'Weekday', from:'9:00', to:'18:00', count:'100' }, { day:'Weekday', from:'9:00', to:'18:00', count:'100' } ]}]";
here b[0] gives me "[" and b[4] gives me "d" so on.
If I understand correctly, var a is JavaScript Object and var b is String.
I am receiving var b from the Java side as a String.
How do I convert var b into a form that I can iterate as I do on var a ?
I have tried :
var c = JSON.parse(b) but getting syntax error.
I really do not wish to change the JSON format much as it is the template used in the Java end as well.
Are there any easy workarounds ?
console screenshot
[{
"defaultCount":"200" ,
"timeintervals": [{ "day":"Weekday", "from":"9:00", "to":"18:00", "count":"100" }, { "day":"Weekday", "from":"9:00","to":"18:00", "count":"100"}]
}]
use double quotes

How can I reformat this simple JSON so it doesn't catch "Circular structure to JSON" exception?

Introduction
I'm learning JavaScript on my own and JSON its something along the path. I'm working on a JavaScript WebScraper and I want, for now, load my results in JSON format.
I know I can use data base, server-client stuff, etc to work with data. But I want to take this approach as learning JSON and how to parse/create/format it's my main goal for today.
Explaining variables
As you may have guessed the data stored in the fore mentioned variables comes from an html file. So an example of the content in:
users[] -> "Egypt"
GDP[] -> "<td> $2,971</td>"
Regions[] -> "<td> Egypt </td>"
Align[] -> "<td> Eastern Bloc </td>"
Code
let countries = [];
for(let i = 0; i < users.length; i++)
{
countries.push( {
'country' : [{
'name' : users[i],
'GDP' : GDP[i],
'Region' : regions[i],
'Align' : align[i]
}]})
};
let obj_data = JSON.stringify(countries, null, 2);
fs.writeFileSync('countryballs.json', obj_data);
Code explanation
I have previously loaded into arrays (users, GDP, regionsm align) those store the data (String format) I had extracted from a website.
My idea was to then "dump" it into an object with which the stringify() function format would format it into JSON.
I have tested it without the loop (static data just for testing) and it works.
Type of error
let obj_data = JSON.stringify(countries, null, 2);
^
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Node'
| property 'children' -> object with constructor 'Array'
| index 0 -> object with constructor 'Node'
--- property 'parent' closes the circle
What I want from this question
I want to know what makes this JSON format "Circular" and how to make this code work for my goals.
Notes
I am working with Node.js and Visual Studio Code
EDIT
This is further explanation for those who were interested and thought it was not a good question.
Test code that works
let countries;
console.log(users.length)
for(let i = 0; i < users.length; i++)
{
countries = {
country : [
{
"name" : 'CountryTest'
}
]
}
};
let obj_data = JSON.stringify(countries, null, 2);
fs.writeFileSync('countryballs.json', obj_data);
});
Notice in comparison to the previous code, right now I am inputing "manually" the name of the country object.
This way absolutely works as you can see below:
Now, if I change 'CountryTest' to into a users[i] where I store country names (Forget about why countries are tagged users, it is out of the scope of this question)
It shows me the previous circular error.
A "Partial Solution" for this was to add +"" which, as I said, partially solved the problem as now there is not "Circular Error"
Example:
for(let i = 0; i < users.length; i++)
{
countries = {
country : [
{
"name" : users[i]+''
}
]
}
};
Resulting in:
Another bug, which I do not know why is that only shows 1 country when there are 32 in the array users[]
This makes me think that the answers provided are not correct so far.
Desired JSON format
{
"countries": {
"country": [
{
"name": "",
"GDP" : "",
"Region" : "",
"Align" : ""
},
{
"name": "",
"GDP" : "",
"Region" : "",
"Align" : ""
},
{
"name": "",
"GDP" : "",
"Region" : "",
"Align" : ""
}
]}
}
Circular structure error occurs when you have a property of the object which is the object itself directly (a -> a) or indirectly (a -> b -> a).
To avoid the error message, tell JSON.stringify what to do when it encounters a circular reference. For example, if you have a person pointing to another person ("parent"), which may (or may not) point to the original person, do the following:
JSON.stringify( that.person, function( key, value) {
if( key == 'parent') { return value.id;}
else {return value;}
})
The second parameter to stringify is a filter function. Here it simply converts the referred object to its ID, but you are free to do whatever you like to break the circular reference.
You can test the above code with the following:
function Person( params) {
this.id = params['id'];
this.name = params['name'];
this.father = null;
this.fingers = [];
// etc.
}
var me = new Person({ id: 1, name: 'Luke'});
var him = new Person( { id:2, name: 'Darth Vader'});
me.father = him;
JSON.stringify(me); // so far so good
him.father = me; // time travel assumed :-)
JSON.stringify(me); // "TypeError: Converting circular structure to JSON"
// But this should do the job:
JSON.stringify(me, function( key, value) {
if(key == 'father') {
return value.id;
} else {
return value;
};
})
The answer is from StackOverflow question,
Stringify (convert to JSON) a JavaScript object with circular reference
From your output, it looks as though users is a list of DOM nodes. Rather than referring to these directly (where there are all sort of possible cyclical structures), if you just want their text, instead of using users directly, try something like
country : [
{
"name" : users[i].textContent // maybe also followed by `.trim()
}
]
Or you could do this up front to your whole list:
const usersText = [...users].map(node => node.textContent)
and then use usersText in place of users as you build your object.
If GDP, regions and align are also references to your HTML, then you might have to do the same with them.
EUREKA!
As some of you have mentioned above, let me tell you it is not a problem of circularity, at first..., in the JSON design. It is an error of the data itself.
When I scraped the data it came in html format i.e <td>whatever</td>, I did not care about that as I could simply take it away later. I was way too focused in having the JSON well formatted and learning.
As #VLAZ and #Scott Sauyezt mentioned above, it could be that some of the data, if it is not well formatted into string, it might be referring to itself somehow as so I started to work on that.
Lets have a look at this assumption...
To extract the data I used the cheerio.js which gives you a kind of jquery thing to parse html.
To extract the name of the country I used:
nullTest = ($('table').eq(2).find('tr').eq(i).find('td').find('a').last());
//"Partial solution" for the OutOfIndex nulls
if (nullTest != null)
{
users.push(nullTest);
}
(nullTest helps me avoid nulls, I will implement some RegEx when everything works to polish the code a bit)
This "query" would output me something like:
whatEverIsInHereIfThereIsAny
or else.
to get rid off this html thing just add .html() at the end of the "jquery" such as:
($('table').eq(2).find('tr').eq(i).find('td').find('a').last().html());
That way you are now working with String and avoiding any error and thus solves this question.

Changing nested attribute with model.set in Backbone

I'm trying to do what I hope is a simple thing -- doing a model.set only on a sub attribute of the object.
Right now, I have a model that looks like this:
{
"attr1" : true,
"attr2" : this.model.get("username"),
"attr3" : $('#tenant_select').val(),
"attr_array": [
{
"id": "sub_1",
"state": "active"
},
{
"id": "sub_22",
"state": "not_active"
}
]
}
I want to be able to grab reach into myMode.attr_array.state and change the value. However, using .set I've only been able to change attributes on the first level, i.e. attr_array.
Is there an way to do this using model.set?
You can do it (I'm wondering why you didn't manage to do it). But you have to be careful:
var array = this.get('attr_array');
array[1].state = 'active';
this.set('attr_array', array);
What's the problem here? Your model holds a reference of the object. Therefore the last line is useless, it won't change anything at all. It's simply equivalent to:
this.get('attr_array')[1].state = 'active';
And you lose any internal stuff Backbone does when you use set.
So what to do? Clone your object:
var array = _.clone(this.get('attr_array'));
array[1].state = 'active';
this.set('attr_array', array); // will trigger 'change' and 'change:attr_array' events

Set value to non existing object

Say i have this object:
test = {
testObj: {
"1": {
"key": "value"
}
}
}
And i want to add values to testObj like so:
test.testObj["2"].key = "my value";
I get error TypeError: Cannot set property 'key' of undefined
Now i do understand that key does not exist yet, but 2 doesn't exist also, and yet i can set value to it:
test.testObj["2"] = "something";
So what can i do about it?
EDIT
wow i feel stupid for not figuring that out by myself... anyways thank you guys.
Javascript doesn't know what test.testObj["2"] should be in this scenario, so it ends up testing it as an existing property:
test.testObj["2"].key = "my value";
The assignment can only apply to the last part of the structure on the left.
But you can tell it what it is by creating the object first:
test.testObj["2"]={};
test.testObj["2"].key = "my value";
Or in a single step:
test.testObj["2"] = { key: "my value"};

Using variable keys to access values in JavaScript objects

The code:
function updateDashboardData() {
$.getJSON("includes/system/ajaxDataInterface.php", {recordcount:1}, function(data) {
$('.stationContainer').each(function(data) {
var bsID = $(this).attr("id");
var bsStatus = $(this).children('.stationStatus');
alert(data[bsID][0].time);
bsStatus.find('.bs_maxHandsets').text(data[bsID][0].maxHandsets);
bsStatus.find('.bs_time').text(data[bsID][0].time);
});
});
}
The object data:
{
"A5A50000": [{
"bsid": "A5A50000",
"chanCount": 17,
"time": "2009-05-27 16:36:45",
"avgInterference": 1.711765,
"maxInterference": 4.97,
"avgHandsets": 205.1176,
"maxHandsets": 315,
"avgCalls": 6.4118,
"maxCalls": 13,
"avgCBA": 3868.98059,
"maxCBA": 7463,
"sumSuccessCBA": 197318,
"sumTimeoutHandoff": 133,
"sumAttemptHandoff": 1028,
"sumDeniedHandoff": 216,
"sumConfirmHandoff": 679,
"sumHandoffNetwork": 61873,
"sumJoinNetwork": 96888,
"sumLeaveNetwork": 93754,
"sumRcvdKeepalive": 98773,
"sumTimeoutKeepalive": 19748,
"sumAttemptUplink": 93689,
"sumBlockedUplink": 62453
}]
}
The problem:
alert(data.A5A50000[0].time); properly displays "2009-05-27 16:36:45".
alert(bsID); properly displays "A5A50000".
alert(data.bsID[0].time); reports "data.bsID is undefined".
alert(data[bsID][0].time); reports "data[bsID] is undefined".
I'm a little unclear when a variable is/isn't evaluated. Maybe I'm overlooking something silly, but I can't figure out my problem here.
You can access object properties by dot notation or by bracket notation.
var x = {'test': 'hi'};
alert(x.test); // alerts hi
alert(x['test']); // alerts hi
When you have a dynamic value, you have to use the latter:
var property = 'test';
alert(x.property); // looks for x.property, undefined if it doesn't exist
alert(x[property]); // looks for x['test'], alerts hi
So what you actually want is:
alert(data[bsID][0].time);
EDIT:
Not sure what you're doing wrong, but this is working for me on Firebug's console:
var data = {"A5A50000":[{"bsid":"A5A50000","chanCount":17,"time":"2009-05-27 16:36:45","avgInterference":1.711765,"maxInterference":4.97,"avgHandsets":205.1176,"maxHandsets":315,"avgCalls":6.4118,"maxCalls":13,"avgCBA":3868.98059,"maxCBA":7463,"sumSuccessCBA":197318,"sumTimeoutHandoff":133,"sumAttemptHandoff":1028,"sumDeniedHandoff":216,"sumConfirmHandoff":679,"sumHandoffNetwork":61873,"sumJoinNetwork":96888,"sumLeaveNetwork":93754,"sumRcvdKeepalive":98773,"sumTimeoutKeepalive":19748,"sumAttemptUplink":93689,"sumBlockedUplink":62453}]};
var bsID = 'A5A50000';
alert(data[bsID][0].time);
In Javascript, you can use either object or array-style notation to look up an attribute. The following are equivalent:
data.A5A50000
data['A5A50000']
With the second syntax, you can use a variable in place of an object string:
data[bsID][0]
I experienced the same problem with a nested JSON API-response:
[
{
"bj_code": "2019",
"BJ_PERIODE": [
{
"nummer": 1
},
{
"nummer": 2
}
]
}
]
I could evaluate:
pm.expect(pm.response.json()[0].BJ_PERIODE[1].nummer).to.eql(2);
But working with BJ_PERIODE and nummer through a variable didn't work.
Writing it with the bracket method did work, even in this nested JSON, like this:
const periode = "BJ_PERIODE";
const nr = "nummer";
pm.expect(pm.response.json()[0][periode][1][nr]).to.eql(2);

Categories

Resources