Object returning undefined - javascript

So I am trying to read a value from a JSON response I am getting from a website. I am trying to get the clan_name from the response. This code
console.log(JSON.stringify(this.steamFriends.clanStates[groupID]));
where groupID is "103582791438731217", returns this object
{
"steamid_clan": "103582791438731217",
"clan_account_flags": 3,
"name_info": {
"clan_name": "Chat Bot Testing & Development",
"sha_avatar": {
"type": "Buffer",
"data": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
"user_counts": {
"members": 20,
"online": 9,
"chatting": 7,
"in_game": 5
},
"events": [],
"announcements": []
}
I am using the code JSON.stringify(this.steamFriends.clanStates[groupID].name_info.clan_name to get the clan_name value from it, but I always get the error "Cannot read name_info of undefined."
Any help on this? Thanks.

JSON.stringify returns a String object.
If the response returns a JSON object, then it's already ready to use... simply use normal object accessor methods to query the property you need. No need to use JSON.stringify.

Related

editing a JSON in JS and putting it in an array

so I have the following json.
{
"BTC": {
"available": 0.00024868,
"onOrder": 0,
"btcValue": 0.00024868,
"btcTotal": 0.00024868
},
"LTC": {
"available": 0,
"onOrder": 0,
"btcValue": 0,
"btcTotal": 0
},
"ETH": {
"available": 0,
"onOrder": 0,
"btcValue": 0,
"btcTotal": 0
},
"NEO": {
"available": 0,
"onOrder": 0,
"btcValue": 0,
"btcTotal": 0
},
"BNB": {
"available": 0.08943066,
"onOrder": 0,
"btcValue": 0.0004663808919,
"btcTotal": 0.0004663808919
}
}
I need to remove the items that don't have a value in the "available" field (such as NEO and ETH and set the result in an array. Then remove the onOrder and btcTotal fields.
such as:
BTC 0.00024868 0.00024868
BNB 0.8943066 0.0004663808919
I am writing my little project in JS on NodeJS as a little hobby project. But, so far all I am able to get right is listing the JSON in the console.
Something like this might work:
const json = `{"BTC":{"available":0.00024868,"onOrder":0,"btcValue":0.00024868,"btcTotal":0.00024868},"LTC":{"available":0,"onOrder":0,"btcValue":0,"btcTotal":0},"ETH":{"available":0,"onOrder":0,"btcValue":0,"btcTotal":0},"NEO":{"available":0,"onOrder":0,"btcValue":0,"btcTotal":0},"BNB":{"available":0.08943066,"onOrder":0,"btcValue":0.0004663808919,"btcTotal":0.0004663808919}}`;
const data = JSON.parse(json);
const processed = Object.entries(data)
.filter(([, { available }]) => available > 0)
.map(([asset, { available, btcValue }]) => {
return { asset, available, btcValue };
});
const asArray = processed.map(Object.values);
console.table(processed);
console.log(asArray);
Object.entries returns an array of key-value pairs. Since it's an array, you can:
call filter method to only keep items where available was greater than 0
call map method to transform the filtered array of key-value pairs into an array of objects (where each object has properties: asset, available, btcValue)
You can get rid of asArray if you want, if it's not useful. It's just to give you an idea of what's possible.

Is there a way to read <script> tag contents

I have a site in which there is a <script> with a JSON inside. With user script in Tampermonkey, I want to get that JSON to work with it later.
So I thought that I can get it with getElemntsByTagName("script"), but I couldn't figure out how to get string out of it.
How do you get a string from getElemntsByTagName("script"), like console.log does?
Is there an easier way to do so?
window.wpProQuizInitList = window.wpProQuizInitList || [];
window.wpProQuizInitList.push({
id: '#wpProQuiz_67',
init: {
quizId: 67,
mode: 2,
globalPoints: 76,
timelimit: 0,
resultsGrade: [0],
bo: 3,
qpp: 0,
catPoints: [76],
formPos: 0,
lbn: "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0438 \u0442\u0435\u0441\u0442",
json: {
"2944": {
"type": "single",
"id": 2944,
"catId": 0,
"points": 1,
"correct": [0,0,1,0]
},
"2945": {
"type": "single",
"id": 2945,
"catId": 0,
"points": 1,
"correct": [0,1,0,0]
},
"2946": {
"type": "single",
"id": 2946,
"catId": 0,
"points": 1,
"correct": [0,0,1,0]
},
…
}
}
}
You can use document.querySelector to get the first <script> element; there is no need to obtain a live HTMLCollection to get one element. You can then read its textContent.
let value = document.querySelector('script').textContent;
getElementsByTagName("script") will return an HTMLCollection which contains a list of script tags. You can get the text of the first script tag like this:
getElementsByTagName("script")[0].innerText

organize MongoDB document to manipulate the data better

I would need help making a data structure with mongodb.
I'm using JavaScript to manipulate data.
I would like to have a document structure of this type, but i'm not sure to do the right thing. I noticed that you tend to use the array also as a container of objects, and i also noticed that the mongodb update operators need a structure of this type. for example:
var mydoc = {
_id: ObjectId("5099803df3f4948bd2f98391"),
items:[ {"name": "name", "other": "other"},
{"name": "name", "other": "other"},
{"name": "name", "other": "other"}
]}
but organize data in this way do not like :) how i would like the document:
{
"_id": {
"$oid": "dfdsdsfdsff54sdf5ds"
},
"displayName": "name",
"userId": "h8566d9482gghffhtry565",
"info": {
"level": 1,
"currentExperience": 0,
"requiredExperience": 0,
"missingExperience": 0
},
"statistics": {
"total": {
"stat1": 0,
"stat2": 0,
"stat3": 0,
"stat4": 0
},
"best": {
"distance": 0,
"stat1": 0,
"stat2": 0,
"stat3": 0,
"stat4": 0
},
"game": {
"one": 0,
"two": 0,
"three": 0,
"stat4": 0
}
},
"inventory": {
"item1": {
"property1": 0,
"property2": 0,
"property3": 0,
"property4": 0,
"level": {
"level": 1,
"currentExperience": 0,
"requiredExperience": 0,
"missingExperience": 0
},
"skins": [
"skin1",
"skin2",
"skin3"
]
},
"item2": {
"property1": 0,
"property2": 0,
"property3": 0,
"property4": 0,
"level": {
"level": 1,
"currentExperience": 0,
"requiredExperience": 0,
"missingExperience": 0
},
"skins": [
"skin1",
"skin2",
"skin3"
]
}
},
"notifications": {},
"rewards": {}
}
Now i explain what the problems im having.
now if i have to change, for example, a property of a specific item that is inside inventory, i take the object "inventory" -> i look for the item i need and then i modify the property.
at the end of this, using an update operator "$set", i replace the "inventory" field.
This may be fine if you have very little data, but within that field there will be hundreds of "sub-field" and this seems like a useless waste resources.
Unfortunately, using $inc operator, i can not pass in any way "the path" of the property that i want to change.
could you help me?
here is what i do now
var userDoc = myCollection("userData");
var userData = userDoc.findOne({"userId": userId}, {items: 1, _id: 0});
//Other code
userData.inventory[itemName][propertyName] = //other code;
userDoc.update({"userId": userId},{"$set": userData});
Thanks,
Regards
If you want to update an embedded document, you can access it using dot notation.
For above document, to update "property1" of "item1" inside "inventory":
db.inventory.update({"userId":"h8566d9482gghffhtry565"},{"$set":{"inventory.item1.property1":"1"}})
the problem is that the "path" is dynamic, I do not know which item will be modified. is the user decide which properties of the items change, I found this solution:
var inc = {$inc: {}};
inc.$inc['inventory.'+itemName+"."+statName] = 1; // itemName and statName are variables created by user
userDoc.update({"userId": userId}, inc);

Why isn't Parse saving the objects in order in the following _.each loop?

I'm looping through an array of objects called $scope.points which looks like this:
[
{"x": 200, "y": 200, "index": 0}
{"x": 200, "y": 200, "index": 1}
{"x": 200, "y": 200, "index": 2}
]
This is the JS, which loops through $scope.points and saves them using Parse:
var createPanodatas = function() {
console.log('POINTS:', $scope.points)
_.each($scope.points, function(point) {
console.log('INDEX:', point.index)
var Panodata = AV.Object.extend('PanoramaData'),
panodata = new Panodata()
var json = {
'index': point.index,
'x': point.x,
'y': point.y,
'roomModelId': $scope.pano.id
}
panodata.save(json, {
success: function(panodata) {
console.log('Panodata saved.')
},
error: function(panodata, error) {
console.log('Failed to create new pano object, with error message: ' + error.message)
}
})
})
}
The saved items are saved ordered by date but with random index:
[
{
"objectId": "56a1e3dc7db2a2005a15533a",
"index": 1,
"roomModelId": "56a1e3d72e958a00515cfe3e",
"createdAt": "2016-01-22T08:10:04.646Z"
},
{
"objectId": "56a1e3dcc24aa8005415772f",
"index": 0,
"roomModelId": "56a1e3d72e958a00515cfe3e",
"createdAt": "2016-01-22T08:10:04.646Z"
},
{
"objectId": "56a1e3dc816dfa005919182b",
"index": 2,
"roomModelId": "56a1e3d72e958a00515cfe3e",
"createdAt": "2016-01-22T08:10:04.670Z"
},
]
Which confused me since console.log('POINTS:', $scope.points) outputs the items in correct index order:
And console.log('INDEX:', point.index) too:
INDEX: 0
INDEX: 1
INDEX: 2
Why are the items saved with random index? How to save the index in order? (e.g. 0, 1, 2 ...)?
This looks like the items are being saved just fine and with the correct index.
The underscore _.each function will iterate through the array in-order as you would expect, which will also result in the creation of the PanoramaData in the same order.
The crucial bit of information to be aware of is that saving with Parse is an asynchronous process and you will have no guarantees about which actually completes first. Intuitively, you would expect that the saves which are executed first would fulfill their promises first and that will probably be the case, however you still cannot make any guarantees about that.
This doesn't seem to be the case in your example since the data appears to be saved just fine, but if you need to know that they are saved in the exact same order as the array then you can use promise chaining, in particular serial promise chaining.
Again, it looks like the data is being properly set but the creation time is causing concern for you since in your example index 1 and 0 both were created at 2016-01-22T08:10:04.646Z. Unless you have a particular use-case for it, try not to rely too heavily on serial processes.

Parsing JSON with jQuery, retrieving two variables.

I have a online JSON file that looks something like this:
[
{
"j": 0,
"i": 0,
"DepartureTime": "\/Date(1331667480000+0100)\/",
"ArrivalTime": "\/Date(1331668860000+0100)\/",
"Remarks": [],
"TravelStages": [
{
"ID": 0,
"DepartureStop": {
"WalkingDistance": 0,
"ArrivalTime": null,
"AlightingAllowed": false,
"DepartureTime": null,
"BoardingAllowed": false,
"RealTimeStop": true,
"Rank": 0,
"Lines": null,
"StopPoints": [
{
"ID": 1,
"Name": "1",
"X": 608127,
"Y": 6645778
}
],
"Zone": "1",
"X": 608133,
"Y": 6645768,
"ID": 2300500,
"Name": "Visperud (i Solheimvn)",
"District": "Lørenskog",
"Type": 0,
"Stops": [],
"ShortName": "VIS"
}]
What I want is the grab out the DepartureTime and ArrivalTime, I've seen some examples on how to parse the flickr JSON. But I can't figure out how I can parse this. I also want to store the departureTime and arrivalTime in two separate variables since the content of this two is a time measured in milliseconds since 1970. Can somebody give me a hint on how a can do this, am totally new to Javascript/JSON
Do you have jQuery in your project? If so, you can easily parse the JSON string like this
var obj = $.parseJSON(theJsonText);
alert(obj.DepartureTime);
If not, I suggest including the JSON library (link) and using that.
You can try something like this, assuming that your json file is in jsonfile.json
$.getJSON('jsonfile.json', function(data){
alert("Departure Time: "+ data.DepartureTime);
alert("Arrival Time: "+ data.ArrivalTime);
});
http://api.jquery.com/jQuery.getJSON/
$.getJSON('http://your.domain.example/path/to/file.json', function(data) {
departure_time=data.DepartureTime;
arrival_time=data.ArrivalTime;
do_something_with(departure_time,arrival_time);
});
then do_something_with(str,str) would be called with the strings "\/Date(1331667480000+0100)\/" and "\/Date(1331668860000+0100)\/" (in your example).
you'll still have to convert the dates to numbers, e.g. by running:
parsed_date=new Date(parseInt(input_string.substr(7)));
//substr(7) cuts after "\/Date(", and parseInt ignores ")\/"
//but I don't know how it handles "+0100"
Thats an array containing objects, so you should be able to just set some vars equal to the properties of the first index. to use it like an object, it needs to be parsed.. so either eval(thatJson) or $.parseJSON(thatJson) and then iterate through it.
var responses = [
{
"j": 0,
"i": 0,
"DepartureTime": "\/Date(1331667480000+0100)\/",
"ArrivalTime": "\/Date(1331668860000+0100)\/",
"Remarks": [],
...
}];
var dep = responses[0].DepartureTime;
var arr = responses[0].ArrivalTime;
According to JSONLint.com, your string isn't valid JSON. That is, however, a different issue than what your question asks for.
Assuming a valid subset of your string
var a = '[{"j": 0,"i": 0,"DepartureTime": "/Date(1331667480000+0100)/", "ArrivalTime": "/Date(1331668860000+0100)/","Remarks": []}]';
var obj = $.parseJSON(a);
console.log(obj[0].ArrivalTime);​

Categories

Resources