0

I'm trying to log my service.title to the console, but it keeps passing it back as a weird object.

.factory('service', function($firebase, FBURL, $routeParams) {
  var ref = new Firebase(FBURL + "services/" + $routeParams.serviceId);
  var title = $firebase(ref.child('title')).$asObject();

  return {
    id: $routeParams.serviceId,
    title: title
  }
})

.controller('ServiceController', function ($scope, $firebase, service, $routeParams, FBURL) {
  $scope.service = service;

  console.log($scope.service.title);
})

Here's what I get back from the console:

enter image description here I'm trying to retrieve that $value in the console log. Can anyone help explain what I might be doing wrong?

Thanks in advance!

Ansel Santosa
  • 8,224
  • 1
  • 28
  • 39
realph
  • 4,481
  • 13
  • 49
  • 104

2 Answers2

4

What you're calling "a weird object" is simply an AngularFire object. Which is pretty much expected, given that you assign it like this:

var title = $firebase(ref.child('title')).$asObject();

When you call $asObject on a simple value, AngularFire keeps the real value in a $value property.

But of course the value is retrieved from the Firebase servers asynchronously, so is not immediately available after you've set up the ref and the called $asObject. So this will not work:

var ref = new Firebase(FBURL + "services/" + $routeParams.serviceId);
var title = $firebase(ref.child('title')).$asObject();
console.log(title.$value);

Instead, you'll need to respond to when it becomes available, for which AngularFore has some nice promises:

var ref = new Firebase(FBURL + "services/" + $routeParams.serviceId);
var title = $firebase(ref.child('title')).$asObject();
title.$loaded().then(function(title) {
  console.log(title.$value);
});

You only need to handle this promise if you want to deal with the data in your own code. If you simply want to bind the title to an AngularJS view (which is what AngularFire was made for), the view will update automatically. Well... not really automatically, it listens for similar promises to resolve. But in that case you won't have to deal with it in your own code.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Ha! I see! I was trying to use `$loaded` to return it before I posted this question, but it wasn't working so I figured I was doing it wrong. Can you help me understand why the value isn't available immediately? – realph Jan 23 '15 at 12:16
  • Two main reasons: 1) since the value is retrieved from a server, it can take some time to be retrieved and the browser cannot simply wait for that. 2) the value might not even exist yet, or be updated during some point. Firebase is all about real-time data **synchronization** and that implies that data changes over time. This topic is covered in quite a few answers already, I recently linked the most interesting ones in this answer: http://stackoverflow.com/questions/27049342/asynchronous-access-to-an-array-in-firebase/27050749#27050749 – Frank van Puffelen Jan 23 '15 at 13:23
1

Definately it will show you the object var title = $firebase(ref.child('title')).$asObject();

Your title is the object

So if you console.log it it will print the object. if you want value use console.log($scope.service.title.$value)

squiroid
  • 13,809
  • 6
  • 47
  • 67
  • This returns `undefined` to the console. – realph Jan 23 '15 at 02:10
  • $scope.service.title has value ...?? I mean as it is showing in the image you attached $value is the child of ('$scope.service.title') so it must be access by chain. – squiroid Jan 23 '15 at 02:14
  • That's what I thought. Very weird. $value is one of the few Meta Fields that are part of that object. Described here. https://www.firebase.com/docs/web/libraries/angular/guide.html I can't seem to get it to return my title, though. – realph Jan 23 '15 at 02:22