gbland777
gbland777

Reputation: 725

Retrieve nested objects JavaScript

My object from Firebase when I console.log:

Object {AW: Object, Qdoba: Object}

Then under the restaurant titles of AW and Qdoba, I have title and address which I can expand on and see in my console. I am wanting to display all the data from both restaurants in my webpage.

How do I access the two restaurant objects without knowing the AW and Qdoba? My code below.

// Initialize Firebase
var config = {
  apiKey: "xxxxxxxx",
  authDomain: "xxxxxxxx",
  databaseURL: "xxxxxxxx",
  storageBucket: "xxxxx.xxxxxx.com",
  messagingSenderId: "xxxxx"
};

firebase.initializeApp(config);

var firebaseRef = firebase.database().ref('listings/');

//load 
firebaseRef.on("value", function(snapshot) {
  document
    .querySelector('#contacts')
    .innerHTML += contactHtmlFromObject(snapshot.val());
});

//prepare object's HTML
function contactHtmlFromObject(item){
  console.log(item)
  var html = '';
  html += '<li class="list-group-item contact">';
    html += '<div>';
      html += '<p class="lead">'+item.title+'</p>';
      html += '<p>'+item.title+'</p>';
      html += '<p><small title="'
                +item.title+'">'
                +item.address
                +'</small></p>';
    html += '</div>';
  html += '</li>';
  return html;
}

My Firebase setup:

 {
  "listings" : {
    "A&W" : {
      "active" : true,
      "address" : "3939",
      "description" : "Super good root beer",
      "title" : "A&W"
    },
    "Qdoba" : {
      "active" : true,
      "address" : "1234 main",
      "description" : "A really good place to eat",
      "title" : "Gellas"
    }
  }
}

Upvotes: 0

Views: 761

Answers (2)

Vanquished Wombat
Vanquished Wombat

Reputation: 9535

Modify your JSON to make a restaurant array and each name an attribute. You then do not need to know the establishment name in order to access the data.

 {
  "listings" : [
    {          
      "name" : "A&W",
      "active" : true,
      "address" : "3939",
      "description" : "Super good root beer",
      "title" : "A&W"
    },
    {
      "name" : "Qdoba",
      "active" : true,
      "address" : "1234 main",
      "description" : "A really good place to eat",
      "title" : "Gellas"
    }
  ]
}

But if you can't do that, for example post-SQL databases may not give you arrays back, then a small piece of script using JQuery-function $.each can walk the objects and output an array of those objects with the key as an attribute.

// this simulates the data being called in via ajax etc.
var data=JSON.parse(' {  "listings" : {    "A&W" : {      "active" : true,      "address" : "3939",      "description" : "Super good root beer",      "title" : "A&W"    },    "Qdoba" : {      "active" : true,      "address" : "1234 main",      "description" : "A really good place to eat",      "title" : "Gellas"    }  }}')

// make a new array to receive the objects
var arr = []
$.each(data.listings, function (key, data) {
    data.name = key // put the object key inside the object as paramater 'name'
    arr.push(data) // put the object into the array
})

// At this point we have an array of objects to do with as we wish.

// Output in readable form.
$("#jsonout").html(JSON.stringify(arr, undefined, 2))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id="jsonout"></pre>

Useful research: Article here justifying why Firebase does not return arrays.

Upvotes: 1

cartant
cartant

Reputation: 58430

Pass the Snapshot itself and use its forEach method to enumerate the items:

firebaseRef.on("value", function(snapshot) {
  document
    .querySelector('#contacts')
    .innerHTML += contactHtmlFromObject(snapshot);
});

function contactHtmlFromObject(snapshot) {
  var html = '';
  snapshot.forEach(function (itemSnapshot) {
    var key = itemSnapshot.key; // This is "A&W" or "Qdoba", etc.
    var val = itemSnapshot.val();
    html += '<li class="list-group-item contact">';
      html += '<div>';
        html += '<p class="lead">'+val.title+'</p>';
        html += '<p>'+val.title+'</p>';
        html += '<p><small title="'
                  +val.title+'">'
                  +val.address
                  +'</small></p>';
      html += '</div>';
    html += '</li>';
  });
  return html;
}

Upvotes: 1

Related Questions