Reading json to create an array of objects with jQuery .each() - javascript

I'm trying to create an array of objects by reading in a json. This is the relevant code:
//president object consctructor
function president(a_presName, a_presDates, a_presNick, a_presImage) {
this.presName=a_presName;
this.presDates=a_presDates;
this.presNick=a_presNick;
this.presImage=a_presImage;
}
var myPres = new Array();
$(document).ready(function() {
$.getJSON('Presidents.json', function(data) {
$.each(data.presidents, function (i, item) {
myPres[i]=new president(item.presName, item.presDates, item.presNick, item.PresImage);
});
}); //end getJSON
document.write(myPres[1].presName);
}); //end doc ready
And this is the json:
{ "presidents": [ { "presName":"George Washington", "presDates":"1789-1797", "presNick":"Father of His Country", "presImage":"gwashington.gif" }, { "presName":"John Adams", "presDates":"1797-1801", "presNick":"Atlas of Independence", "presImage":"jadams.gif" }, { "presName":"Thomas Jefferson", "presDates":"1801-1809", "presNick":"Sage of Monticello", "presImage":"tjefferson.gif" }, { "presName":"James Madison", "presDates":"1809-1817", "presNick":"Father of the Constitution", "presImage":"jmadison.gif" }, { "presName":"James Monroe", "presDates":"1817-1825", "presNick":"Era-of-Good-Feeling President", "presImage":"jmonroe.gif" }, { "presName":"John Quincy Adams", "presDates":"1825-1829", "presNick":"Old Man Eloquent", "presImage":"jqadams.gif" }, { "presName":"Andrew Jackson", "presDates":"1829-1837", "presNick":"Old Hickory", "presImage":"ajackson.gif" }, { "presName":"Martin Van Buren", "presDates":"1837-1841", "presNick":"The Little Magician", "presImage":"mvanburen.gif" }, { "presName":"William Henry Harrison", "presDates":"1841", "presNick":"Old Tippecanoe", "presImage":"whharrison.gif" }, { "presName":"John Tyler", "presDates":"1841-1845", "presNick":"Accidental President", "presImage":"jtyler.gif" }, { "presName":"James Knox Polk", "presDates":"1845-1849", "presNick":"Young Hickory", "presImage":"jkpolk.gif" }, { "presName":"Zachary Taylor", "presDates":"1849-1850", "presNick":"Old Rough and Ready", "presImage":"ztaylor.gif" }, { "presName":"Millard Fillmore", "presDates":"1850-1853", "presNick":"The American Louis Philippe", "presImage":"mfillmore.gif" }, { "presName":"Franklin Pierce", "presDates":"1853-1857", "presNick":"Young Hickory of the Granite Hills", "presImage":"fpierce.gif" }, { "presName":"James Buchanan", "presDates":"1857-1861", "presNick":"Old Buck", "presImage":"jbuchanan.gif" }, { "presName":"Abraham Lincoln", "presDates":"1861-1865", "presNick":"Honest Abe", "presImage":"alincoln.gif" }, { "presName":"Andrew Johnson", "presDates":"1865-1869", "presNick":"None", "presImage":"ajohnson.gif" }, { "presName":"Ulysses Simpson Grant", "presDates":"1869-1877", "presNick":"Hero of Appomattox", "presImage":"usgrant.gif" }, { "presName":"Rutherford Birchard Hayes", "presDates":"1877-1881", "presNick":"Dark-Horse President", "presImage":"rbhayes.gif" }, { "presName":"James Abram Garfield", "presDates":"1881", "presNick":"None", "presImage":"jagarfield.gif" }, { "presName":"Chester Alan Arthur", "presDates":"1881-1885", "presNick":"The Gentleman Boss", "presImage":"caarthur.gif" }, { "presName":"Grover Cleveland", "presDates":"1885-1889", "presNick":"None", "presImage":"gcleveland.gif" }, { "presName":"Benjamin Harrison", "presDates":"1889-1893", "presNick":"Kid Gloves Harrison", "presImage":"bharrison.gif" }, { "presName":"Grover Cleveland", "presDates":"1893-1897", "presNick":"None", "presImage":"gcleveland.gif" }, { "presName":"William McKinley", "presDates":"1897-1901", "presNick":"Idol of Ohio", "presImage":"wmckinley.gif" }, { "presName":"Theodore Roosevelt", "presDates":"1901-1909", "presNick":"Trust-Buster", "presImage":"troosevelt.gif" }, { "presName":"William Howard Taft", "presDates":"1909-1913", "presNick":"None", "presImage":"whtaft.gif" }, { "presName":"Woodrow Wilson", "presDates":"1913-1921", "presNick":"Schoolmaster in Politics", "presImage":"wwilson.gif" }, { "presName":"Warren Gamaliel Harding", "presDates":"1921-1923", "presNick":"None", "presImage":"wgharding.gif" }, { "presName":"Calvin Coolidge", "presDates":"1923-1929", "presNick":"Silent Cal", "presImage":"ccoolidge.gif" }, { "presName":"Herbert Clark Hoover", "presDates":"1929-1933", "presNick":"None", "presImage":"hchoover.gif" }, { "presName":"Franklin Delano Roosevelt", "presDates":"1933-1945", "presNick":"FDR", "presImage":"fdroosevelt.gif" }, { "presName":"Harry S. Truman", "presDates":"1945-1953", "presNick":"Give 'Em Hell Harry", "presImage":"hstruman.gif" }, { "presName":"Dwight David Eisenhower", "presDates":"1953-1961", "presNick":"Ike", "presImage":"ddeisenhower.gif" }, { "presName":"John Fitzgerald Kennedy", "presDates":"1961-1963", "presNick":"JFK", "presImage":"jfkennedy.gif" }, { "presName":"Lyndon Baines Johnson", "presDates":"1963-1969", "presNick":"LBJ", "presImage":"lbjohnson.gif" }, { "presName":"Richard Milhous Nixon", "presDates":"1969-1974", "presNick":"None", "presImage":"rmnixon.gif" }, { "presName":"Gerald Rudolph Ford", "presDates":"1974-1977", "presNick":"Jerry", "presImage":"grford.gif" }, { "presName":"James Earl Carter Jr.", "presDates":"1977-1981", "presNick":"Jimmy", "presImage":"jecarter.gif" }, { "presName":"Ronald Wilson Reagan", "presDates":"1981-1989", "presNick":"The Gipper", "presImage":"rwreagan.gif" }, { "presName":"George Herbert Walker Bush", "presDates":"1989-1993", "presNick":"Poppy", "presImage":"ghwbush.gif" }, { "presName":"William Jefferson Clinton", "presDates":"1993-2001", "presNick":"Bill", "presImage":"wjclinton.gif" }, { "presName":"George Walker Bush", "presDates":"2001-2009", "presNick":"W", "presImage":"gwbush.gif" }, { "presName":"Barack Hussein Obama", "presDates":"2009-", "presNick":"None", "presImage":"bhobama.gif" } ] }
When I use the document.write to test it works fine if it's placed right before }); //end getJSON, but if it's place immediately after it is null. What am I missing?

Placing the document.write after //end getJSON means it will run before the JSON is retrieved.
The anonymous function you pass to .getJSON is called when the data comes back from the server. If you run the document.write after the //end getJSON it is called before the request comes back.

I don't like jQuery's $.each()
I would do it like this:
function parseJSON(JSONObj){
var array=new Array();
var count=0;
for(var Obj in JSONObj){
array[count]=JSONObj[Obj];
count++;
}
}
Please tell me if it is anything else you wanted

Related

Vue-js call object with special id

I'm a newbie in Vue-js and really need your help:
In my Django project I have 2 models: Patient and MedCard of this patient. They are connected with a Foreign Key. I want to implement such functionality: on page "Patients" I have list of patients, then when I push on someone's name I want to see his/her MedCard.
This is my code, but when I push on name I get all records for all patients from MedCard model:
Patients.vue:
<div v-for="patient in patients">
<h3 #click="openMedCard(patient.id)">{{patient.surname}} {{patient.name}}</h3>
<p>{{patient.birth_date}}</p>
</div>
<div
<MedCard v-if="med_record.show" :id="med_record.id"></MedCard>
</div>
export default {
name: 'Patient',
components: {
MedCard,
},
data() {
return {
patients: '',
med_record: {
patient: '',
show: false,
}
}
}
and methods from Patient.vue:
methods: {
openMedCard(id) {
this.med_record.patient = id
this.med_record.show = true
}
MedCard.vue:
<template>
<mu-row v-for="med_record in med_records">
<h3>Doc – {{med_record.doc.surname}}{{med_record.doc.name}}</h3>
<p>{{med_record.patient.surname}}</p>
<p>{{med_record.record}}</p>
<small>{{med_record.date}}</small>
</mu-row>
</template>
export default {
name: 'MedCard',
props: {
id: '',
},
data() {
return {
med_records: '',
}
},
methods: {
loadMedCard() {
$.ajax({
url: "http://127.0.0.1:8000/api/v1/hospital/med_card/",
type: "GET",
data: {
id: this.id,
patient: this.patient
},
success: (response) => {
this.med_records = response.data.data
}
})
}
}
}
loadMedCard() gives me info from all MedCards in JSON like this:
{
"data": {
"data": [
{
"id": 1,
"patient": {
"id": 1,
"surname": "KKK",
"name": "KKK",
"patronymic": "LLL",
"birth_date": "1999-07-07",
"sex": "F",
"phone": "no_phone",
"email": "no_email"
},
"doc": {
"id": 3,
"surname": "DDD",
"name": "DDD",
"patronymic": "DDD",
"education": "d",
"category": "2",
"sex": "m",
"phone": "no_phone",
"email": "no_email"
},
"record": "test text",
"date": "2020-06-09"
}...]
I'll be grateful for any help!
So the API returns you multiple patients's data while you're asking it for just one exact patient. There must be something wrong with the API with the filtering in first place. So you can filter your data on the client side, in your MedCard.vue component. First this component have to show data for one patient only, so the v-for="med_record in med_records" is not needed. Your med_records property can become just an object not an array:
data() {
return {
med_record: {},
}
}
And in the success resolve method of your API call you can filter only the data you need and store it in med_record
success: (response) => {
this.med_records = response.data.data.find((patient)=> { return patient.id === this.id})
}
If you want to store all the data in the med_records, then you can create computed property and apply the same filtering there.
I hope this helps.

click on a list item to get the relevant information from a JSON file to update the HTML with the correct data

I'm looking to update the text content on the html page with the relevant information from the JSON file.
At the moment, I'm able to populate the drop down menu, with players name from the JSON file. But I'm not sure how to target a list item, when it has been clicked on and populate the players stats with the correct data from the JSON file.
Below is my code, any help or guidance would be great as I'm stuck for the past couple of days now.... Thanks in advance!
Here is the HTML
<body>
<section class="player-card">
<!-- player-dropDown -->
<div class="player-dropDown">
<ul class="player-dropDown__disable">
<li id="disable"> Select a player... </li>
<ul class="player-dropDown__select">
<li class="select"> Toby Alderweireld </li>
</ul>
</ul>
</div>
<!-- player-img -->
<div class="player-img">
<img src="./img/toby.png">
</div>
<!-- player-stats -->
<div class="player-stats">
<h1 class="player-stats__name">Toby Alderweireld</h1>
<h2 class="player-stats__position">Defender</h2>
<div class="player-stats__badge">
<div id="player-stats__badge-icon"></div>
</div>
<div class="player-stats__container">
<div class="player-stats__box player-stats__box-space clear">
<p class="player-stats__box-name"> Appearances </p>
<p id ="appearances" class="player-stats__box-value"> 80 </p>
</div>
<div class="player-stats__box player-stats__box-space clear">
<p class="player-stats__box-name"> Goals </p>
<p id="goals" class="player-stats__box-value"> 5 </p>
</div>
<div class="player-stats__box player-stats__box-space clear">
<p class="player-stats__box-name"> Assists </p>
<p id="assists" class="player-stats__box-value"> 2 </p>
</div>
<div class="player-stats__box player-stats__box-space clear">
<p class="player-stats__box-name"> Goals per match </p>
<p id="goals-per-match" class="player-stats__box-value"> 0.06 </p>
</div>
<div class="player-stats__box clear">
<p class="player-stats__box-name"> Passes per minute </p>
<p id="passes-per-min" class="player-stats__box-value"> 0.26 </p>
</div>
</div>
</div>
</section>
<script type="text/javascript" src="js/index.js"></script>
Here is my JS
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Parse JSON file from string to object
var response, players;
response = JSON.parse(xhttp.responseText);
players = response.players;
// toggle menu
function toggleMenu() {
var DropDownBtn, DropDownMenu;
DropDownBtn = document.getElementById('disable');
DropDownMenu = document.querySelector('.player-dropDown__select');
DropDownBtn.onclick = function() {
DropDownMenu.classList.toggle('show');
console.log('menu clicked');
}
}
// dropDownNameOutput
function menuNameOutput() {
var menuNameOutput;
menuNameOutput = '';
// loop through JSON file
for ( var i = 0; i < players.length; i++ ) {
var playerID,
playerFirstName,
playerLastName,
appearance,
goals,
assists,
goalsPerMatch,
goalsPerMatchDecimal,
passesPerMin,
fwdPasses,
bwdPasses,
minsPlayed,
passesPerMinDecimal;
// from the JSON file log the players stats
playerID = players[i].player.id;
playerFirstName = players[i].player.name.first;
playerLastName = players[i].player.name.last;
appearance = players[i].stats[6].value;
goals = players[i].stats[0].value;
assists = players[i].stats[5].value;
fwdPasses = players[i].stats[4].value;
bwdPasses = players[i].stats[8].value;
minsPlayed = players[i].stats[7].value;
goalsPerMatch = goals / appearance;
goalsPerMatchDecimal = goalsPerMatch.toFixed(2);
passesPerMin = (fwdPasses + bwdPasses) / minsPlayed;
passesPerMinDecimal = passesPerMin.toFixed(2);
// populate the drop down menu with players names & ID
menuNameOutput += '<li id="' + playerID + '"' + ' ' + 'class="select">' + playerFirstName + ' ' + playerLastName + '</li>';
};
// output the players name & ID to the menu (HTML)
document.querySelector('.player-dropDown__select').innerHTML = menuNameOutput;
};
toggleMenu();
menuNameOutput();
}
};
xhttp.open("GET", "JSON/player-stats.json", true);
xhttp.send();
Here is the JSON
{
"players":[
{
"player":{
"info":{
"position":"D",
"shirtNum":4,
"positionInfo":"Centre/Right Central Defender"
},
"nationalTeam":{
"isoCode":"BE",
"country":"Belgium",
"demonym":"Belgian"
},
"age":"27 years 139 days",
"name":{
"first":"Toby",
"last":"Alderweireld"
},
"id":4916,
"currentTeam":{
"name":"Tottenham Hotspur",
"teamType":"FIRST",
"shortName":"Spurs",
"id":21
}
},
"stats":[
{
"name":"goals",
"value":5
},
{
"name":"losses",
"value":20
},
{
"name":"wins",
"value":48
},
{
"name":"draws",
"value":23
},
{
"name":"fwd_pass",
"value":1533
},
{
"name":"goal_assist",
"value":2
},
{
"name":"appearances",
"value":80
},
{
"name":"mins_played",
"value":6953
},
{
"name":"backward_pass",
"value":308
}
]
},
{
"player":{
"info":{
"position":"M",
"shirtNum":42,
"positionInfo":"Centre Defensive Midfielder"
},
"nationalTeam":{
"isoCode":"CI",
"country":"Cote D'Ivoire",
"demonym":"Ivorian"
},
"age":"33 years 67 days",
"name":{
"first":"Yaya",
"last":"Touré"
},
"id":4148,
"currentTeam":{
"name":"Manchester City",
"teamType":"FIRST",
"shortName":"Man City",
"id":11
}
},
"stats":[
{
"name":"goals",
"value":65
},
{
"name":"losses",
"value":49
},
{
"name":"wins",
"value":149
},
{
"name":"draws",
"value":35
},
{
"name":"fwd_pass",
"value":4491
},
{
"name":"goal_assist",
"value":35
},
{
"name":"appearances",
"value":232
},
{
"name":"mins_played",
"value":18919
},
{
"name":"backward_pass",
"value":1995
}
]
},
{
"player":{
"info":{
"position":"F",
"shirtNum":10,
"positionInfo":"Left/Centre/Right Second Striker"
},
"nationalTeam":{
"isoCode":"GB-ENG",
"country":"England",
"demonym":"English"
},
"age":"30 years 269 days",
"name":{
"first":"Wayne",
"last":"Rooney"
},
"id":2064,
"currentTeam":{
"name":"Manchester United",
"teamType":"FIRST",
"shortName":"Man Utd",
"id":12
}
},
"stats":[
{
"name":"goals",
"value":201
},
{
"name":"losses",
"value":91
},
{
"name":"wins",
"value":280
},
{
"name":"draws",
"value":90
},
{
"name":"fwd_pass",
"value":1795
},
{
"name":"goal_assist",
"value":84
},
{
"name":"appearances",
"value":461
},
{
"name":"mins_played",
"value":27056
},
{
"name":"backward_pass",
"value":1928
}
]
},
{
"player":{
"info":{
"position":"D",
"shirtNum":4,
"positionInfo":"Centre Central Defender"
},
"nationalTeam":{
"isoCode":"DE",
"country":"Germany",
"demonym":"German"
},
"age":"31 years 294 days",
"name":{
"first":"Per",
"last":"Mertesacker"
},
"id":4246,
"currentTeam":{
"name":"Arsenal",
"teamType":"FIRST",
"shortName":"Arsenal",
"id":1
}
},
"stats":[
{
"name":"goals",
"value":8
},
{
"name":"losses",
"value":45
},
{
"name":"wins",
"value":117
},
{
"name":"draws",
"value":41
},
{
"name":"fwd_pass",
"value":4257
},
{
"name":"goal_assist",
"value":0
},
{
"name":"appearances",
"value":187
},
{
"name":"mins_played",
"value":16531
},
{
"name":"backward_pass",
"value":535
}
]
},
{
"player":{
"info":{
"position":"M",
"shirtNum":26,
"positionInfo":"Left/Right Winger"
},
"nationalTeam":{
"isoCode":"DZ",
"country":"Algeria",
"demonym":"Algerian"
},
"age":"25 years 149 days",
"name":{
"first":"Riyad",
"last":"Mahrez"
},
"id":8983,
"currentTeam":{
"name":"Leicester City",
"teamType":"FIRST",
"shortName":"Leicester",
"id":26
}
},
"stats":[
{
"name":"goals",
"value":22
},
{
"name":"losses",
"value":23
},
{
"name":"wins",
"value":35
},
{
"name":"draws",
"value":21
},
{
"name":"fwd_pass",
"value":687
},
{
"name":"goal_assist",
"value":14
},
{
"name":"appearances",
"value":71
},
{
"name":"mins_played",
"value":5368
},
{
"name":"backward_pass",
"value":323
}
]
}
]
}
Here is some example code you can paste into the body element of an html file.
It contains only two players for simplicity.
The HTML employs a select element, each of whose option children has a player's full name as its visible text and that player's playerId as its invisible value.
Selecting an option triggers a function that:
1)uses the playerId to find the corresponding player data in the global players object,
2)stores that data in the global selectedPlayer object, and
3)demonatrates how to retrieve specific values from that selectedPlayer.
(Retrieving values -- including the player objects, which use the player's playerId as their keys -- is made a bit simpler by the fact that the JSON contains no arrays, only objects.)
<select id="dropdown" onchange="respondToSelection()">
<option value="0000">Some Player</option>
<option value="4246">Per Mertesacker</option>
</select>
<script>
// Global identifiers
const
dropdown = document.querySelector("#dropdown"),
opts = dropdown.options,
jsonString = getJsonString(),
players = JSON.parse(jsonString); // Javascript object containing all players' info
let selectedPlayer; // Object will hold info for whichever player is selected
function respondToSelection(){
// Handles user input by populating the selectedPlayer object with the corresponding data
const
index = dropdown.selectedIndex,
selected = opts[index],
text = selected.text,
playerId = selected.value;
console.log(`text from dropdown: ${text}`);
console.log(`playerId from dropdown: ${playerId}`);
selectedPlayer = players[playerId]; // Stores the selected player's info in the selectedPlayer object
// Now we can get any property within the selected player by using dot notation like:
const
country = selectedPlayer.player.nationalTeam.country,
goals = selectedPlayer.stats.goals;
console.log(`country: ${country}`);
console.log(`goals: ${goals}`);
}
function getJsonString(){
return `{
"4246" : {
"player": {
"info": { "position" : "D", "shirtNum" : 4, "positionInfo" : "Centre Central Defender" },
"nationalTeam": { "isoCode" : "DE", "country" : "Germany", "demonym" : "German" },
"age": "31 years 294 days",
"name": { "first" : "Per", "last" : "Mertesacker" },
"id": "4246",
"currentTeam": { "name" : "Arsenal", "teamType" : "FIRST", "shortName" : "Arsenal", "id" : 1 }
},
"stats": {
"goals" : 8,
"losses" : 45,
"wins" : 117,
"draws" : 41,
"fwd_pass" : 4257,
"goal_assist" : 0,
"appearances" : 187,
"mins_played" : 16531,
"backward_pass" : 535
}
},
"0000" : {
"player": {
"info": { "position" : "D", "shirtNum" : 0, "positionInfo" : "Some Position" },
"nationalTeam": { "isoCode" : "DE", "country" : "Germany", "demonym" : "German" },
"age": "29 years 29 days",
"name": { "first" : "Some", "last" : "Player" },
"id": "0000",
"currentTeam": { "name" : "Arsenal", "teamType" : "FIRST", "shortName" : "Arsenal", "id" : 1 }
},
"stats": {
"goals" : 1,
"losses" : 1,
"wins" : 1,
"draws" : 1,
"fwd_pass" : 57,
"goal_assist" : 0,
"appearances" : 18,
"mins_played" : 531,
"backward_pass" : 35
}
}
}`
}
</script>

Keen.io how to use savedQueries() to chart graph

I'm trying to use savedQueries to draw graph without success. Is savedQueries only used to CRUD queries in Keen or can it actually be used to chart graph as well?? Keys removed from the code, sorry for the inconvenience.
var client = new Keen({
projectId: keen.project,
writeKey: keen.writeKey,
readKey: keen.readKey,
masterKey: keen.masterKey
});
var savedQueries = client.savedQueries();
savedQueries.get("monthly-active-users", function(err, response) {
if (err) {
console.log(err);
}
console.log(response);
var chart1 = new Keen.Dataviz()
.el(document.getElementById('chart'))
.chartType("area")
.colors(["#6ab975"])
.title("Monthly Active Users")
.prepare();
chart1
.data(response)
.render();
});
response obj from saved query
{
"refresh_rate": 0,
"user_last_modified_date": "2017-06-09T18:51:59.676000+00:00",
"last_modified_date": "2017-06-09T18:51:59.676000+00:00",
"query_name": "monthly-active-users",
"urls": {
"cached_query_url": "/3.0/projects/58f6fb8a90b3659264951b8d/queries/saved/monthly-active-users",
"cached_query_results_url": "/3.0/projects/58f6fb8a90b3659264951b8d/queries/saved/monthly-active-users/result"
},
"created_date": "2017-04-25T23:52:45.685000+00:00",
"query": {
"filters": [
{
"operator": "ne",
"property_name": "user_id",
"property_value": "guest"
},
{
"operator": "not_contains",
"property_name": "fromState",
"property_value": "app"
},
{
"operator": "not_contains",
"property_name": "user_email",
"property_value": "#giblib.com"
},
{
"operator": "not_contains",
"property_name": "fromState",
"property_value": "app.auth_postregister"
}
],
"analysis_type": "count_unique",
"timezone": "US/Pacific",
"group_by": null,
"force_exact": null,
"timeframe": "this_2_months",
"target_property": "user_id",
"interval": "monthly",
"event_collection": "user-page-access"
},
"run_information": null,
"metadata": {
"visualization": {
"chart_type": "areachart"
},
"display_name": "Monthly Active Users"
}
}
I noticed that you did not include the Keen.ready() function. Also, I recommend using client.run instead of client.get because it runs the query and gets the result.
I went ahead and created an example JSFiddle: https://jsfiddle.net/pn14bs0L/2/
Keen.ready(function() {
client.run("test-saved-query", function(err, response) {
if (err) {
// there was an error
} else {
var chart1 = new Keen.Dataviz()
.el(document.getElementById('my_chart'))
.chartType("areachart")
.colors(["#6ab975"])
.title("Monthly Active Users")
.prepare();
chart1
.data(response)
.render();
}
});
});
You can see this working with some test data in the JSFiddle.
Note: I assumed you were using keen-js here and not keen-dataviz.js.

Parse: JavaScript Promises issue

I am trying to wrap my head around Promises, then , when, and everything else that goes along with it. I am not having much success. Here is what I'm trying to accomplish in English, and maybe somebody can crack the code because so far nothing I've written works.
I am writing a SPA (single page app) for mobile devices. Essentially all the content is is one giant HTML page with a bunch of DIV's. However, only one DIV is shown at a time. The user will have a tab bar to click on each of the icons to show/hide DIV's. Think of something like the Apple App Store interface with "Featured", "Top Charts", "Explore", "Search", and "Updates" at the bottom.
Parse database query of table Businesses for 1 business with AppUrl=example.com
Resulting business objectId is used to query table Navigation for all pieces of the navigation. Things like "Home", "About Us", "Menus", "Events", "Contact", etc.
Resulting navigation items are looped to render DIV's with content in them. The content comes from the tables below depending on the Module column:
"Home" = Photos table
"About Us" = Pages table
"Menus" = Lists table
"Event" = Lists table
That's basically it. Pretty simple, but obviously there are nest queries within #4. I don't know if I should be creating one giant object in my queries and then outputting that? Or creating a bunch of different objects with arrays inside of them? Really kind of lost since this style of syntax is different than say PHP. Advice?
Here is my non-database connected version:
app.get('/', function(req, res){
var frontpageImages = [
{ caption:"Eggplant, Prosciutto, and Pesto Pressed Sandwiches.", file:"image01.jpg", position:"15%" },
{ caption:"Pico de Gallo", file:"image02.jpg", position:"75%" },
{ caption:"B.L.A.T Croque Madame", file:"image03.jpg", position:"20%" },
{ caption:"Double Oreo Brownie Cupcake", file:"image04.jpg", position:"80%" },
{ caption:"Baked Chicken Chimichangas with Monterey Jack Cheese Sauce", file:"image05.jpg", position:"20%" }
]
var menu = [
{ divider:"Appetizers" },
{ name:"French Fries", picture:"menu-french-fries", subname:"$4.95" },
{ name:"Loaded Cheese Fries", picture:"menu-cheese-fries", subname:"$7.95" },
{ name:"Gaelic Chips", picture:"menu-gaelic-chips", subname:"$2.95" },
{ name:"Jalapeno Mac n' Cheese", picture:"menu-jalapeno-mac-n-cheese", subname:"$4.95" },
{ name:"Chicken Wings", picture:"menu-chicken-wings", subname:"$8.50" },
{ name:"Irish Nachos", picture:"menu-irish-nachos", subname:"$8.50" },
{ name:"Black & Tan Onion Rings", picture:"menu-onion-rings", subname:"$6.95" },
{ name:"Mac's Quesadillas", picture:"menu-quesadillas", subname:"$8.50" },
{ name:"Banger Bites", picture:"menu-banger-bites", subname:"$7.95" },
{ divider:"Salads" },
{ name:"Caesar Salad", picture:"menu-caesar-salad", subname:"$6.50" },
{ name:"House Salad", picture:"menu-house-salad", subname:"$6.50" },
{ name:"Buffalo Chicken Salad (Grilled or Battered)", picture:"menu-buffalo-chicken-salad", subname:"$8.95" },
{ divider:"Sandwiches & Burgers" },
{ name:"Rueben", picture:"menu-reuben", subname:"$8.50" },
{ name:"Dublin Corned Beef", picture:"menu-corned-beef-sandwich", subname:"$8.50" },
{ name:"Philly Cheese Steak", picture:"menu-philly-cheese-steak", subname:"$8.50" },
{ name:"Grilled Chicken", picture:"menu-grilled-chicken-sandwich", subname:"$8.50" },
{ name:"Club Sandwich", picture:"menu-club-sandwich", subname:"$8.50" },
{ name:"Not-So-Irish Burger", picture:"menu-irish-burger", subname:"$9.95" },
{ name:"Dirty Burger", picture:"menu-dirty-burger", subname:"$7.95" },
{ name:"Aurora Burger", picture:"menu-aurora-burger", subname:"$10.95" },
{ name:"Bleu Cheese Burger", picture:"menu-bleu-cheese-burger", subname:"$11.95" },
{ name:"Additional Burger Toppings", picture:"menu-burger-toppings", subname:"$0.50" },
{ divider:"Irish Favorites & Entrees" },
{ name:"Beer Battered Fish N' Chips", picture:"menu-fish-and-chips", subname:"$11.50" },
{ name:"Bangers And Mash", picture:"menu-bangers-and-mash", subname:"$10.95" },
{ name:"Shepherd's Pie", picture:"menu-shepherds-pie", subname:"$10.95" },
{ divider:"Brunch" },
{ name:"Irish Breakfast", picture:"menu-irish-breakfast", subname:"$11.50" },
{ name:"American Breakfast", picture:"menu-american-breakfast", subname:"$11.50" },
{ name:"Irish Breakfast Roll", picture:"menu-irish-breakfast-roll", subname:"$8.95" },
{ name:"English Muffin, Scrambled Eggs, Cheddar and Irish Rasher", picture:"menu-irish-rasher", subname:"$7.50" },
{ name:"3 Egg Omelette", picture:"menu-omelette", subname:"$6.50" },
{ name:"Eggs Benedict", picture:"menu-eggs-benedict", subname:"$8.50" },
{ name:"3 Pancakes with Maple Syrup", picture:"menu-pancakes", subname:"$6.00" },
{ name:"Grilled Turkey and Swiss", picture:"menu-grilled-turkey-and-swiss", subname:"$7.00" }
];
var drinks = [
{ name: "Bahama Bomb", desc: "Bacardi 151 Rum, Cruzan Coconut Rum, Creme de Banana, Pineapple juice, and Sprite.", subname: "$9.95" },
{ name: "Tropical Margarita", desc: "Grand Marnier, Cruzan Coconut Rum, Blue Curacao, sour mix, and orange juice. Garnished with lemon, lime, and cherry.", subname: "$10.95" },
{ name: "LOL[emonade]", desc: "Absolute Citron, Triple Sec, muddled lemon and simple syrup, sour mix, and Sprite.", subname: "$9.95" }
];
var events = [
{ divider:"Upcoming Events" },
{ name: "Super Bowl Party", subname: "1/28" },
{ name: "Valentine's Singles Party", subname: "2/14" },
{ divider:"Weekly Events" },
{ name: "Hospitality Night", subname: "Monday" },
{ name: "Trivia Night", subname: "Tuesday" },
{ name: "Karaoke with Liam", subname: "Thursday" }
];
res.render('index', {
nav:[
{ name:"Home", title:"Clark's Bar and Grille", url:"home", icon:"home", module:"home", run:"startSlider", source:frontpageImages },
{ name:"Menu", url:"menu", icon:"cutlery", module:"list", source:menu },
{ name:"Drinks", url:"drinks", icon:"glass", module:"list", source:drinks },
{ name:"Events", url:"events", icon:"calendar", module:"list", source:events },
{ name:"Restaurant Info", title:"Restaurant Info", url:"business-info", icon:"info-circle", module:"business-info" },
{ name:"Instagram Feed", title:"Instagram", url:"instagram", icon:"instagram", module:"instagram", run:"startInstagram" },
{ name:"Like and Follow Us", title:"Social Media", url:"social-media", icon:"thumbs-up", module:"social-media-links" },
{ name:"Contact Clark's", title:"Contact Clark's", url:"contact", icon:"envelope", module:"contact" }
]
});
});
When the page renders now, I have the index.ejs loop the nav object and display each DIV (Home, Menu, Drinks, Events, etc). Each array within the nav object has a key called source which returns the objects for them listed above. The page renders perfectly, it's just not connected to a database. I would like to swap all that out with a DB connected version!
I hope this code will help you, that's the best I can suggest with what you provided:
function handleError(message, error) {
//Handle any error here, for example:
console.error(message, error);
res.send(500, message);
}
var responseContent = {
nav: [],
};
getBusiness(); //start fetching data
function getBusiness() {
var businessQuery = /*query to get element AppUrl=example.com*/;
businessQuery.first().then(
getNavigation,
handleError.bind(null, 'error getting business'));
}
function getNavigations(business) {
var navigationsQuery = /*query to get navigation elements*/;
var promises = [];
navigationsQuery.each(function (navigation) {
promises.push(processNavigation(navigation));
}).then(
function () {
Parse.Promise.when(promises).then(
renderResult,
handleError.bind(null, 'error processing navigations'));
},
handleError.bind(null, 'error iterating navigations'));
}
function processNavigation(navigation) {
var promise = Parse.Promise();
var nav = {
name: /*name*/,
url: /*url*/,
};
responseContent.nav.push(nav);
switch (/*module*/) {
case 'Home':
getPhotosContent(/*args*/).then(
function (source) {
nav.source = source;
promise.resolve();
},
function (error) {
promise.reject(error);
}
);
break;
//can do similar code for 'About Us', 'Menus', ...
default:
promise.resolve();
}
return promise;
}
function getPhotosContent(/*args*/) {
var promise = Parse.Promise();
var results = [];
var photosQuery = /*query to get photos*/;
photosQuery.each(function (photo) {
results.push(photo);
}).then(
function () {
promise.resolve(results);
}, function (error) {
promise.reject(error);
}
);
return promise;
}
function renderResult() {
res.render('index', responseContent);
}

how to get complex json object and render it in views in node js?

I have following json with arrays in it
In server I'm sending json like this
getTrips: function getTrips(req, res, next){
var url = '/CTB-WS/rest/trips?from='+ req.tripinfo.fromCityId + '&to=' + req.tripinfo.toCityId + '&depart-date=' + req.tripinfo.departDate+ '&pax=1';
console.log(url);
rest.get(url).on('complete', function(trips) {
if (trips instanceof Error) {
console.log('Error:', trips.message);
} else {
console.log('trips'+ JSON.stringify(trips));
console.log('onward trips'+ JSON.stringify(trips['onwardTrips']));
trips = trips || [];
req.trips = trips['onwardTrips'];
next();
}
});
},
sendTrips: function sendTrips(req, res, next){
res.render('trips', { trips: req.trips});
}
In view , I'm able to catch trip id, but not pickupPointDetails and dropoffPointDetails which are inside array, how can I render it in view?
extends layout
block content
h3 Trip Selection
form.form-horizontal(id="Findtrips", accept-charset="UTF-8", action="", method="post" enctype="multipart/form-data")
each trip, key in trips
p
a(href="") #{trip.tripId} #{key} #{trips.length}
p= trip.pickupPointDetails[0].pickupPointId //[0] [1] works but when i give key as value Unexpected token =
JSON object
{
"onwardTrips": [
{
"tripId": "1285758",
"fromCity": "Singapore",
"toCity": "Shah Alam",
"operatorCode": "SA",
"operatorName": "Starmart Express",
"departTime": "2014-01-24 11:30:00.0",
"busType": "Executive",
"pickupPointDetails": [
{
"pickupPointId": "78",
"departureTime": "2014-01-24 11:30:00.0",
"pickupPointName": "Golden Mile Tower, Beach Road"
}
],
"dropoffPointDetails": [
{
"dropOffPointName": "Shah Alam Bus Terminal",
"dropOffPointId": "1285758"
}
],
"fareDetails": {
"adultFare": "91.0"
}
},
{
"tripId": "1285856",
"fromCity": "Singapore",
"toCity": "Shah Alam",
"operatorCode": "SA",
"operatorName": "Starmart Express",
"departTime": "2014-01-24 21:00:00.0",
"busType": "Executive",
"pickupPointDetails": [
{
"pickupPointId": "78",
"departureTime": "2014-01-24 21:00:00.0",
"pickupPointName": "Golden Mile Tower, Beach Road"
}
],
"dropoffPointDetails": [
{
"dropOffPointName": "Shah Alam Bus Terminal",
"dropOffPointId": "1285856"
}
],
"fareDetails": {
"adultFare": "91.0"
}
}
],
"errorCode": 0
}
You need to nest another loop if you wish to access each object in the sub array:
Example JSON object:
{
"array": [
{
"property": "Hello",
"nestedArray": [
{
"nestedArrayProp": "World"
}
]
}
]
}
Example Jade template:
each object in array
each nestedObject in object.nestedArray
p= object.property + ' ' + nestedObject.nestedArrayProp
Which will output:
<p>Hello World</p>

Categories