using node.js to parse multi-dimensional census data - javascript

I am attempting to pull out individual rows and specific data from the census data using node.js JSON.parse.
const http = require('http');
function printStuff(statesInfo){
const statesPopulations = `${statesInfo} This is all states info`;
console.log(statesPopulations);
}
const request = http.get(`http://api.census.gov/data/2013/acs5?get=NAME,B01001_001E&for=state:*&key=4c2f7253819e5491c78ff2c5ed541fe95943854c`,
response => {
let body = "";
console.log('Status Code:', response.statusCode);
response.on('data', data=> {
body += data.toString();
});
response.on('end', () => {
const statePop = JSON.parse(body);
const statesInfo = JSON.parse(body);
printStuff(statesInfo);
})
});
Using console.log(body) the results show up as...
NAME,B01001_001E,state,Alabama,4799277,01,Alaska,720316,02,Arizona,6479703,04,Arkansas,2933369,05,California,37659181,06,Colorado,51
19329,08,Connecticut,3583561,09,Delaware.......
if I use console.dir(body), the results show up as....
[[NAME][B01001][state]
['Alabama', '4799927', '01'],
[ 'Alaska', '720316', '02' ]] ....
all the way down to Puerto Rico. I am trying to pull specific things out but examples I've been using on Treehouse are set up all nice and neat where you can pull specifically labeled things out using nice things like profile.badges.length, but from what I can tell, none of these things are labelled. I would like to be able to say, pull Virginia's info out of there, or Delaware.

Most likely the examples you are seeing on Treehouse use an object with keys {Alabama: {...}} instead of the array that you get back from census.gov [["Alabama", ...]].
To access California's population you need to get the 6th(index 5 since its 0 based) nested array from the parent. Which looks like this:
get the California array
console.log(statePop[5]); // outputs ["California","37659181","06"]
get the population of California by getting the second item in the California array.
console.log(statePop[5][1]); // outputs "37659181"
If you want a more human readable version(like Treehouse examples) you would have to create an object with keys from the array. You could do this easily with something like lodash or manually like so:
var popByState = {};
// loop through each state and assign values to object keyed by the state name
statePop.forEach(function(stateArr) {
popByState[stateArr[0]] = {population: stateArr[1]};
// Ex stateArr = ["California","37659181","06"]
// stateArr[0] is the name of the state
// stateArr[1] is the population
});
console.log(popByState.California.population) // outputs "37659181";
But then you have to be aware of states that have a space in their name like "New York". You can't use dot notation to access these(console.log(popByState.New York.population)) you have to use brackets console.log(popByState['New York'].population)

Related

Extract specific nested array in JSON Objects that match data with Javascript

I'm working with an NBA API where one of the features is finding players by their last name.
The issue I have; is that multiple players can have the same last name, of course.
An example of the response from the API when sorting with last names:
"players": [
0: {
"firstName":"Anthony"
"lastName":"Davis"
"teamId":"17"
"yearsPro":"9"
"collegeName":"Kentucky"
"country":"USA"
"playerId":"126"
"dateOfBirth":"1993-03-11"
"affiliation":"Kentucky/USA"
"startNba":"2012"
"heightInMeters":"2.08"
"weightInKilograms":"114.8"
1: {
"firstName":"Deyonta"
"lastName":"Davis"
"teamId":"14"
"yearsPro":"3"
"collegeName":"Michigan State"
"country":"USA"
"playerId":"127"
"dateOfBirth":"1996-12-02"
"affiliation":"Michigan State/USA"
"startNba":"2016"
"heightInMeters":"2.11"
"weightInKilograms":"107.5"
}
I limited the results here, but it goes on and on, etc.
So, I am looking to do two things:
First, extract/filter the correct player using their first name and last name.
In said extraction, I still need the complete array information when it is matched.
So essentially, I want 'Deyonta Davis', but when found - I also need the rest of said player's information (years pro, college, country, etc.)
I already have a command set up to retrieve the first result of the nested data in this API via last name - where the command takes the last name you input and sends the first result. The precise problem is that the first result is likely not to be the guy you are looking for.
The goal is to include first & last name to avoid pulling the wrong player.
A snippet of how I currently call the information via last name:
// Calling API
const splitmsg = message.content.split(' ')
var lastnameurl = "https://api-nba-v1.p.rapidapi.com/players/lastName/" + splitmsg[1];
axios.get(lastnameurl, {
headers: {
"x-rapidapi-key": apikey,
"x-rapidapi-host": apihost
}
// Extracting Player Information (first result)
var playerfirstname = response.data.api.players[0].firstName;
var playerlastname = response.data.api.players[0].lastName;
var collegename = response.data.api.players[0].collegeName;
var countryname = response.data.api.players[0].country;
var playerDOB = response.data.api.players[0].dateOfBirth;
var yrspro = response.data.api.players[0].yearsPro;
var startednba = response.data.api.players[0].startNba;
Any help would be appreciated, thank you.
If I understand the question correctly the task is:
Retrieve first matching object from an array where properties firstName and lastName equal to desired values.
To achieve this you could use build in find function.
const player = array.find(el => {
return el.firstName === "Deyonta" && el.lastName === "Davis"
});
Keep in mind if there is no such object in array the player will be undefined.

LocalStorage Setting Object Inside Array Ionic List

I am trying to use LocalStorage to store an array that contains objects. Right now the following code is returning an object on the console and not returning as an array. This means that my ion-list cannot read it. Is there any way around this and getting back the value as an array with my objects in the array? The object presentation contains multiple things such as ID, title, etc etc. I want to be able to store multiple presentations in the array and be able to access each one and display them in the ion list.
Manager.js
playlistService.addPlaylistAll = function (presentation) {
console.log("setting item");
var playlistarraytest = [];
playlistarraytest.push(presentation);
console.log("array first!! ", playlistarraytest);
localStorage.setItem('playlisttest', playlistarraytest);
playlistService.refresh();
var test = localStorage.getItem('playlisttest');
console.log(test);
}
Playlist.html
<ion-list ng-repeat="presentation in dayOne = (playlist | filter: { day: 1 } | orderBy: 'start_date')">
You cannot store data structures directly in LocalStorage. LocalStorage only stores strings. So you must use:
let json = JSON.stringify(playlistarraytest);
localStorage.setItem('playlisttest', json);
And then to retrieve it use:
var test = localStorage.getItem('playlisttest');
let arr = JSON.parse(test);
console.log(arr);

javascript - JSON file use a value only if key exists

I'm retrieving an OSM Json from an overpass call, to obtain a list of features that I have to save on a database. Since the data are very different from one another (for example, some of them do have a a tag called "addr:city", and some of them not), I would like to check if a key exists, and only in that case save the corresponding value. I've found only this question but it's not my case, since I do not know a priori which keys one element will have and which not, and since I'm working with a great load of data, I really can't check the elements one by one and of course I can't write an IF for each case.
Is there a way to solve this? I was thinking something about "if key has null value, ignore it", while looping over the elements, but I don't know if something like that exists
EDIT:
This is my query:
https://overpass-api.de/api/interpreter?data=[out:json][timeout:25];(node[~%22^(tourism|historic)$%22~%22.%22](44.12419,%2012.21259,%2044.15727,%2012.27696);way[~%22^(tourism|historic)$%22~%22.%22](44.12419,%2012.21259,%2044.15727,%2012.27696););out%20center;
and this is the code I'm using to save the data on firebase:
results.elements.forEach(e=>{
var ref = firebase.database().ref('/point_of_interest/');
var key = firebase.database().ref().child('point_of_interest').push().key;
var updates = {};
var data = {
città: e.tags["addr:city"],
tipologia: e.tags["amenity"],
indirizzo: e.tags["addr:street"],
nome: e.tags["name"],
lat: e.lat,
lon: e.lon
}
updates['/point_of_interest/'+key] = data;
firebase.database().ref().update(updates);
})
"results" is the response in json format
You could use something like that:
var attrs = ["addr:city", "amenity", "addr:street", "name"];
var labels = ["città", "tipologia", "indirizzo", "nome"]
var data = { };
attrs.forEach((a, i) => {
if (e.tags[a]) { data[labels[i]] = e.tags[a]; }
});
You could even make this more dynamic, if you can query the attribute names and labels from somewhere.

Looping through deeply nested properties - React

I'm trying to .map through data returned from an API (the NASA API). The issue I'm having is with deeply nested properties -- here's an example.
What's the best way to get the nested name and estimated_diameter properties data in React? All the data's being brought in just fine via axios. Logging out the state returns this:
I'm having trouble map'ing through the data because of the nested objects and arrays.
Assume the nasa data json is saved in the variable nasaData, the code below will print all the name and the estimated_diameter
var nearEarthObjects = nasaData['near_earth_objects'];
for (var property in nearEarthObjects) {
if (nearEarthObjects.hasOwnProperty(property)) {
var data = nearEarthObjects[property];
data.forEach(function(d){
console.log(d['name']);
console.log(d['estimated_diameter']);
});
}
}
ps: this might be for a reactjs project but it's really just javascript
You can map through the dates first.
const { near_earth_objects } = nasaData; //assuming nasaData is the json object
const dateKeys = Object.keys(near_earth_objects);
const nameAndEstimatedDiameters = dateKeys.map((dateKey) => {
const dateData = near_earth_objects[dateKey];
const { name, estimated_diameter } = dateData;
return { name, estimated_diameter };
});
//now nameAndEstimatedDiameters is an array of objects here
//which you can map again

How to pull only the nodes/values from firebase and not the keys?

How do you only pull only the nodes from firebase and not the keys using javascript? In other words, I only want the values of the key-value pairs from the below firebase, which means I don't want the unique keys below but just what's underneath.
Currently, my code is..
function PullFirebase() {
new Firebase('https://myfirebase.firebaseIO.com/quakes').on('value', function (snapshot) {
var S = snapshot.val();
function printData(data) {
var f = eval(data);
console.log(data + "(" + f.length + ") = " + JSON.stringify(f).replace("[", "[\n\t").replace(/}\,/g, "},\n\t").replace("]", "\n]"));
}
printData(S);
});
}
PullFirebase();
This produces the following in the console
[object Object](undefined) = {"-JStYZoJ7PWK1gM4n1M6":{"FID":"quake.2013p618454","agency":"WEL(GNS_Primary)","depth":"24.5703","latitude":"-41.5396","longitude":"174.1242","magnitude":"1.7345","magnitudetype":"M","origin_geom":"POINT (174.12425 -41.539614)","origintime":"2013-08-17T19:52:50.074","phases":"17","publicid":"2013p618454","status":"automatic","type":"","updatetime":"2013-08-17T19:54:11.27"},
"-JStYZsd6j4Cm6GZtrrD":{"FID":"quake.2013p618440","agency":"WEL(GNS_Primary)","depth":"26.3281","latitude":"-38.8725","longitude":"175.9561","magnitude":"2.6901","magnitudetype":"M","origin_geom":"POINT (175.95611 -38.872468)","origintime":"2013-08-17T19:45:25.076","phases":"13","publicid":"2013p618440","status":"automatic","type":"","updatetime":"2013-08-17T19:48:15.374"},...
but I'd like to only have the dictionaries , such as
[{"FID":"quake.2013p618454","agency":"WEL(GNS_Primary)","depth":"24.5703","latitude":"-41.5396","longitude":"174.1242","magnitude":"1.7345","magnitudetype":"M","origin_geom":"POINT (174.12425 -41.539614)","origintime":"2013-08-17T19:52:50.074","phases":"17","publicid":"2013p618454","status":"automatic","type":"","updatetime":"2013-08-17T19:54:11.27"},{"FID":"quake.2013p597338","agency":"WEL(GNS_Primary)","depth":"5.0586","latitude":"-37.8523","longitude":"176.8801","magnitude":"2.2362","magnitudetype":"M","origin_geom":"POINT (176.88006 -37.852307)","origintime":"2013-08-10T00:21:54.989","phases":"17","publicid":"2013p597338","status":"automatic","type":"","updatetime":"2013-08-10T03:42:41.324"}...]
If I understand you correctly, you want to get all child objects under quakes.
You generally have two approach here:
Get the value of the parent node and loop over the children
Monitor as children are added/updated/removed to the parent node
Your approach matches with #1, so I'll answer that one first. I'll also give an example of approach #2, which is more efficient when your data set changes.
Iterate children of a Firebase ref
In your on('value', handler you can skip the unique IDs using forEach:
new Firebase('https://myfirebase.firebaseIO.com/quakes').on('value', function (snapshot) {
var quakes = [];
snapshot.forEach(function(childSnapshot) {
quakes.push(childSnapshot.val());
});
var filter = new crossfilter(quakes);
});
The forEach function is sychronous, so we can simply wait for the loop to finish and then create the crossfilter.
Monitor children of a Firebase ref
In that case, the best construct is:
var quakes = new Firebase('https://myfirebase.firebaseIO.com/quakes');
var quakeCount = 0;
quakes.on('child_added', function (snapshot) {
var quake = snapshot.val();
quakeCount++;
console.log("quakeCount="+quakeCount+", FID="+quake.FID);
});
quakes.on('child_removed', function (old_snapshot) {
var quake = old_snapshot.val();
quakeCount--;
console.log("quakeCount="+quakeCount+", removed FID="+quake.FID);
});
With this code construct you're actively listening for quakes that are added and removed. You'll still have to keep an array of all the quakes, which you then modify in child_added, child_changed and child_removed.
How they compare
When you first run the code, monitoring for children will result in the same data as the on('value', construct. But when children are added/removed later on('value', will receive all quakes again, while on('child_added', and on('child_removed', will only be called for the quake in question.

Categories