Getting undefined when trying to acces a JSON item [closed] - javascript

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
i am trying to get a JSON and access its objects to retrieve data, all my paths seems to be working good but one specifically is not working. I just checked and the path is the same the other objects i am trying to access, in the console i keep getting undefined as a result. i will appreciate if you guys could tell me whats wrong with the code i will leave you the JSON structure and also the java Scripti hope you guys can help me figuring out, and also would be good if you could give me some tips on my coding because I am learning.
Java Script:
This function is called when you click on some item in a list.
function checkUser(){
console.log("clicked");
var user = $(this).html();
$.getJSON("js/options.json", function(json){
var itemsLength = json.chat.OnlineContacts.length;
for ( var i = 0; i < itemsLength; i++) {
var jsonUserName = json.chat.OnlineContacts[i].name;
var jsonUserStatus = json.chat.OnlineContacts[i].status;
var jsonUserAvatar = json.chat.OnlineContacts[i].avatar;
if(user == jsonUserName){
/*displayChatWindow(jsonUserName, jsonUserStatus, jsonUserAvatar);*/
console.log(jsonUserAvatar);
}
};
});
}
function displayChatWindow(user, status, avatar){
/*var template = _.template($("#windowTemplate").html(), {userName: user, userStatus: status, userAvatar: avatar});
$("body").prepend(template);*/
$(".messages-container").slimScroll({
height: '200',
size: '10px',
position: 'right',
color: '#535a61',
alwaysVisible: false,
distance: '0',
railVisible: true,
railColor: '#222',
railOpacity: 0.3,
wheelStep: 10,
disableFadeOut: false,
start: "bottom"
});
}
And this is the JSON:
{
"chat": {
"NumberOfOnlineContacts": "7",
"NumberOfOfflineContacts": "800",
"OnlineContacts": [
{
"name": "Nandy Torres",
"status": "online",
"avatar": "img/profile-picture2.jpg"
},
{
"name": "Catherine Varela",
"status": "Busy",
"avatar": "img/profile-picture3.jpg"
},
{
"name": "Jhonnatan Gonzalez",
"status": "online",
"avatar": "img/profile-picture4.jpg"
},
{
"name": "Juan Prieto",
"status": "away",
"avatar": "img/profile-picture5.jpg"
},
{
"name": "Alexander Barranco",
"status": "Busy",
"avatar": "img/profile-picture6.jpg"
}
],
"OfflineContacts": [
{
"name": "Nandy Torres"
},
{
"name": "Catherine Varela"
},
{
"name": "Jhonnatan Gonzalez"
},
{
"name": "Juan Prieto"
},
{
"name": "Jhonathan Sanchez"
}
]
}
}
When I try to do the console log on avatar like is in the example I just get undefined, but if i do console.log of name or status y just get the correct values.

Consider restructuring the original JSON object so you can access users directly by their unique id - in this case it appears to be "name".
For example:
{
"chat": {
"NumberOfOnlineContacts": "7",
"NumberOfOfflineContacts": "800",
"OnlineContacts": [
{
"Nandy Torres" : {
"status": "online",
"avatar": "img/profile-picture2.jpg"
}
},
{
"Catherine Varela" : {
"status": "Busy",
"avatar": "img/profile-picture3.jpg"
}
},
{...}
]
}
}
This could be accessed in the following ways without the expense of a loop:
json.chat.OnlineContacts[0].avatar
json.chat.OnlineContacts["Nandy Torres"].avatar
json.chat.OnlineContacts[user].avatar
There's an obvious cost-benefit here, but you may get the best of both by inlcuding the "name" attr as well:
"Nandy Torres" : {
"name": "Nandy Torres",
"status": "online",
"avatar": "img/profile-picture2.jpg"
}
And eventually moving to a more formal unique id:
"123abc" : {
"name": "Nandy Torres",
"status": "online",
"avatar": "img/profile-picture2.jpg"
}
There's lots of excellent ideas for structuring JSON at json.com

Jhonnatan, I'm glad you got your code working. So this isn't really an "answer" to your original question. But you also asked for tips on the coding and how to improve it. That's great that you're looking for ways to improve your code!
Here's one suggestion for you, a simpler way to write the checkUser() function. This is just a direct conversion of your function that should work with the same data format.
function checkUser() {
console.log( "clicked" );
var user = $(this).html();
$.getJSON( "js/options.json", function( json ) {
$.each( json.chat.OnlineContacts, function( i, contact ) {
if( user == contact.name ) {
displayChatWindow( contact.name, contact.status, contact.avatar );
console.log( contact.avatar );
}
});
});
}
Note how the use of the contact object makes it unnecessary to create all those jsonUserXxxx variables, because code like contact.avatar is just as simple and clear as jsonUserAvatar.
I also highly recommend #DaveRomero's excellent answer for a more strategic look at the question of how best to structure your JSON data.
More related reading: this discussion of JSON restructuring that I posted in response to this question earlier today.

Related

Firebase how to Order by child on js

I can't order a message with timestamp , I tried many ways and it still doesn't work, please help
An arrangement with data like pictures
code
database
data:
{ chatRoom : {
"232": {
"-NKHmBkCihoyRiYABX5O": {
"createdAtDate": "2022-12-27",
"createdAtTime": "17:52:49",
"fromType": 4,
"message": "message2",
"readByAdmin": false,
"readByUser": true,
"timestamp": 1672131169.174558,
"user": "tuan do",
"userId": "232"
}
},
"242": {
"-NKHm6svnBJhWq321aNv": {
"createdAtDate": "2022-12-27",
"createdAtTime": "17:52:29",
"fromType": 3,
"message": "message1",
"readByAdmin": false,
"readByUser": true,
"timestamp": 1672131149.252743,
"user": "solashi 歯科衛生士",
"userId": "242"
}
}
}
}
code : const dbRefAdmin = firebase.database().ref('chatRoom').orderByChild('timestamp').limitToLast(10)
A simple answer :
Try to use "orderBy" instead of "orderByChild"
then "limit" instead of "limitToLast"
Give a feedback in comment and put your post in solved status if the code below solves your problem.
Official documentation : order and limit data with Cloud Firestore
var is_start_load = true;
const dbRefAdmin = firebase.database().ref('chatRoom').orderBy('timestamp').limit(10);

Facebook Graph API - Ads Insights with different Action Values from Post

I'm using facebook Graph API to retrieve action values from campaigns. But the JSON returned is always different from any values from facebook screen.
My Request from JavaScript
var d = new FormData();
d.append("access_token", "MY_ADS_INSIGHTS_TOKEN");
d.append("fields", "actions");
d.append("date_preset", "lifetime"); // I want lifetime data
return await (await fetch("https://graph.facebook.com/v3.1/" + campaignid + "/insights", {
method: "post",
body: d
})).json();
and after I access the report insights using the URL:
https://graph.facebook.com/v3.1/REPORT_RUN_ID/insights?access_token=MY_ADS_INSIGHTS_TOKEN
JSON returned after access report task
{
"data": [
{
"actions": [
{
"action_type": "comment",
"value": "2"
},
{
"action_type": "like",
"value": "4"
},
{
"action_type": "photo_view",
"value": "30"
},
{
"action_type": "post",
"value": "1"
},
{
"action_type": "link_click",
"value": "7"
},
{
"action_type": "page_engagement",
"value": "249"
},
{
"action_type": "post_engagement",
"value": "245"
},
{
"action_type": "post_reaction",
"value": "205"
}
],
"date_start": "2018-07-09",
"date_stop": "2018-07-15",
"ad_id": null // removed
}
],
"paging": {
"cursors": {
"before": "MAZDZD",
"after": "MAZDZD"
}
},
"__fb_trace_id__": null // removed
}
Facebook Post Results
I want to know:
Why Facebook Graph API return the post_reaction as 205 since from facebook view it is 160 or 150? the value doesn't match anything, happens to action like too
Notes:
I'm not using any SDK, but this isn't the problem.
The Ad has only ONE ads group and the group has only ONE campaign
I make the requisition at the same time as I see the post. There are no major interactions in this post, it is old enough that the values do not change.
I known that Facebook cache anything, but this Ad is from 10, July.
Ad Campaign Insights reference: https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group/insights/
I accept answers using SDKs or different programming languages like C#, php or Java as example, I want only know HOW make the right request or what is exactly happening.

Web scraping dynamic content with phantomjs

Im trying to scrape data from a site that generates its data via a javascript but I cant seem to locate the invoking script. When I look at the page source there is an in-page script that has a variable which has an array of the data I wish to retrieve but there is another script which contains all the codes for the various companies I wish to retrieve data from. This is what i've tried so far:
var url = 'http://www.asx.com.au/asx/share-price-research/company/ZAM/details';
var page = require('webpage').create();
page.open(url, function (status) {
var digitalData = page.evaluate(function () {
return window.digitalData;
})page.then(function (digitalData) {
console.log
}
('DigtalData is ' + digitalData));
phantom.exit();
});
Unfortunately the above script doesnt output anything. The script which contains the codes for the companies I want to get the data from I think is this:
var locationPath = window.location.pathname.split('/');
var companyCode = locationPath[locationPath.length - 1].trim();
var sectorCodes = {
"MOQ": "soft",
"1PG": "soft",
"ONT": "heal",
"1ST": "heal",
"T3D": "food",
"TGP": "real",
"TIX": "real",
"TDO": "ener",
"DDD": "mate",
"3PL": "cons",
"4DS": "semi"
};
setTimeout(function () {
googletag.cmd.push(function () {
googletag.defineSlot('/76291182/ASX_leaderboard_com_info', [728, 90], 'div-gpt-ad-1450158832871-0').addService(googletag.pubads());
googletag.defineSlot('/76291182/ASX_MREC_com_info', [[300, 250], [300, 600]], 'div-gpt-ad-1450158832871-1').addService(googletag.pubads());
googletag.defineSlot('/76291182/ASX_MREC_lower_com_info', [300, 250], 'div-gpt-ad-1450158832871-2').addService(googletag.pubads());
googletag.defineSlot('/76291182/ASX_skyscraper_com_info', [160, 600], 'div-gpt-ad-1450158832871-3').addService(googletag.pubads());
googletag.defineSlot('/76291182/ASX_half_page_com_info', [300, 600], 'div-gpt-ad-1450158832871-4').addService(googletag.pubads());
googletag.pubads().setTargeting("cc", companyCode);
if (typeof sectorCodes[companyCode] != 'undefined') {
googletag.pubads().setTargeting('sec', sectorCodes[companyCode]);
}
googletag.enableServices();
});
}, 2000);
This script seems to do a lot more than just contain the codes for the companies but its the only JS script I can find that has the company codes. I believe the data I want is from this script:
var currentURL = (document.URL);
var part = currentURL.split("/")[6];
// var dwsDTM = $('#company-code-title').text();
var digitalData = {
"page": {
"pageInfo": {
"pageID": "3345",
"pageName": "Company info " + part,
"pageURL": window.location.href,
"issueDate": "n/a",
"updatedDate": "n/a",
"brand": "ASX",
"generator": "OpenText",
"domain": "Website",
"sysEnv": "",
"delayType": "Normal"
},
"category": {
"primaryCategory": "Prices and research",
"subCategory1": "Company information",
"subCategory2": "Company info " + part,
"subCategory3": "",
"pageType": ""
},
"productInfo": {}
},
"user": {
"profileInfo": {
"memberB2B": "",
"businessMemberID": "",
"memberRetail": "",
"retailMemberID": ""
},
"version": "1.0",
"events": [],
"vendor": {
"GoogleAnalytics": {
"account": "UA-9950793-3",
"eventCategory": ""
}
}
}
};
I believe its generated to this HTML:
<div class="view-content" ui-view></div>
Im new to scraping dynamic content and this looks so hard to do. Could someone point me in the right direction to retrieve this data?
Thanks
UPDATE: So after a few hours of playing on the site I figured out that they use angularJS for their data call backs and upon further playing around I found the links they use to store their data. They have an API but I dont think its publicly available. In any case I think I can write a simple DOM Script to retrieve and format the data. Will keep you all posted
I figured out a solution. Utilising their API and using HTML DOM and PHP I was able to retrieve the data I wanted and then output the data to CSV. I cant discuss my code or the API because it would be in violation of their terms and service.

d3pie error: no data supplied on d3pie.js

I am using rails, and gathering some data to make pie charts. I am just using ruby objects (so no JSON), and using d3pie. First, I make a helper function. Then I make a javascript function using that helper, and pass it in the dom. Here's my code;
helper.rb
def options_data_to_d3(options_data)
d3_data = []
options_data.each do |key, value|
d3_data.push( { label: key.option.as_json, value: value.as_json } )
end
return JSON.pretty_generate(d3_data)
end
this takes the ruby hash, and makes it into json
js function
function dataPieChart(id, data) {
var config = {
"header": {
"title": {
"text": "Quiz Questions",
"fontSize": 18,
"font": "verdana"
},
"size": {
"canvasHeight": 400,
"canvasWidth": 500
},
"data": {
"content": data
},
"labels": {
"outer": {
"pieDistance": 32
}
}
}
}
var pie = new d3pie(id, config);
}
passing into the view
<div id="quizQuestionOptionPie<%= question.id %>"></div>
<script type="text/javascript">dataPieChart("quizQuestionOptionPie<%= question.id %>", <%= raw options_data_to_d3(data[:options]) %>);
</script>
when I call a console log in the javascript function to see what data is, I get the correct output that both d3pie and d3 are looking for, yet I am still getting the error
d3pie error: no data supplied.
does anyone see something wrong with my code, or something I am missing? any help is appreciated.
You config option is bracketed incorrectly (everything is a child of "header"). You really meant:
var config = {
"header": {
"title": {
"text": "Quiz Questions",
"fontSize": 18,
"font": "verdana"
},
},
"size": {
"canvasHeight": 400,
"canvasWidth": 500
},
"data": {
"content": data
},
"labels": {
"outer": {
"pieDistance": 32
}
}
};

AngularJS - parsing JSON feed with namespace

New to angular, and it is awesome.
One thing I am having a brain fart on is parsing a JSON feed that contains namespaces:
Example from JSON feed:
"title": {
"label": "Fuse"
},
"im:name": {
"label": "John Doe"
},
"im:image": [ {
"label": "70x70",
"attributes": {
"height": "55"
}
}, {
"label": "80x80",
"attributes": {
"height": "60",
"im:link": "www.google.com"
}
}, {
"label": "90x90",
"attributes": {
"height": "170"m
"im:link": "www.yahoo.com"
}
}],
I can successfully parse items without namespaces fine like so:
<p ng-repeat="item in results.feed['entry']">
title: {{item.title['label']}}
</p>
But cannot get the items with namespaces to display using:
name: {{item.['im:name']['label']}}
OR
name: {{item.['im-name']['label']}}
OR
name: {{item.['im->name']['label']}}
Since being a newbie, I thought something like this would work:
<div xmlns:im="http://www.aol.com" id="im-app" im-app="im">
<p ng-repeat="item in results.feed['entry']">
…namespace code in here…
</p>
</div>
But that did not help.
Extra bonus question: What if a namespace contains attributes, that also contain namespaces?
Any help would greatly be appreciated.
Thanks!
Roc.
Although Craig answered the question,
This is also for reference for others:
If you want to target a specific key inside of an object set:
"im:image":[
{
"label":google",
"attributes":{
"height":"55"
}
},
{
"label":"yahoo",
"attributes":{
"height":"60"
}
},
{
"label":"aol",
"attributes":{
"height":"170"
}
}
{{item['im:image'][2]['label']}}
Will get the 3rd key in that set.
Thanks.
Get rid of the dot after item
Working example: http://jsfiddle.net/bonza_labs/Kc2uk/
You access the properties exactly the same way as straight javascript (because angular is basically eval()-ing the expression as javascript**). item.['foo'] is not valid javascript. You are correct in using square-bracket notation as my:name is not valid for dot-notation.
valid:
item.foo
item['foo']
with non-standard property names:
item['foo:bar']
item['foo-bar']
and in your case:
{{item['im:name']['label']}}
** or close enough for understanding this solution

Categories