-1

This is getting very very very annoying now... Im stuck on this for a long time... The problem is it is getting slow on loading.. This is my code i will explain at the bottom about it:

app.controller('chatCtrl', ["$scope", function($scope) {


        var ref = new Firebase('MYFIREBASEAPP')
        $scope.usernameProfile = ''
        $scope.imageProfile = ''


        ref.onAuth(function(authData) {
            ref.child("Users Auth Info").child(authData.uid).on("value", function(snapshot) {
                $scope.usernameProfile = snapshot.val().Username;
                $scope.imageProfile = snapshot.val().Image
                console.log(snapshot.val().Image)
                console.log(snapshot.val())
                console.log($scope.usernameProfile)
                var username = $scope.usernameProfile
                console.log($scope.imageProfile)
            })
        })


        console.log($scope.usernameProfile)
        console.log($scope.imageProfile)

    }])

Here i am getting the usernameProfile and imageProfile from the data of the user... The problem here is that it loads wayyy to slow.. that when i try to render it to html by passing:

<img id="profileImage" ng-src="{{imageProfile }}"  >

The image becomes blank.. for some reason the html dosent recognize the ng-model... also in my code above the ones at the bottom gets logged first then the others in the snapshot.val().. Please Please Help me.. Thankyou

EDIT

Tried this... still dosent work...

   var ref = new Firebase('https://sparke.firebaseio.com/')
    var syncObject = $firebaseObject(ref);

    ref.onAuth(function(authData){
      $scope.profile = $firebaseObject(ref.child('UsersAuthInfo').child(authData.uid).child("Image"));
    $scope.profile.$loaded().then(function() {
        console.log($scope.profile.$value);
        $scope.imageProfile = $scope.profile.$value
        });
    })

EDIT

This dosent work:

ref.onAuth(function(authData) {
             console.log("Good?)
  ref.child("UsersAuthInfo").child(authData.uid).on("value", function(snapshot) {
      $timeout(function() {
      $scope.usernameProfile = snapshot.val().Username;
      $scope.imageProfile = snapshot.val().Image
      console.log(snapshot.val())
    });
  })
})

console.log($scope.usernameProfile)

The one at the first which says Good, gets executed first then the bottom one then the one inside .child()

EDIT3

Ok frank. Before i started, i just deleted the quotes and made it simpler...

Lets get started with the problem of $timeout...

So when i tested the $timeout for the original plunker(the simpler version...) It worked really fine This is the code:

ref.child('Image').on("value", function(snapshot) {
  // tell AngularJS that we're going to make changes to $scope
  $timeout(function(){
    $scope.image = snapshot.val();
    console.log(snapshot.val())
  });
}, function (errorObject) {
  console.log("The read failed: " + errorObject.code);
})

Now with the timeout when i tried to implement that to my original app it didnt work unforutunately for some reason... here is the code for that..:

ref.onAuth(function(authData){
  ref.child("UsersAuthInfo").child(authData.uid).on("value", function(snapshot) {
    // tell AngularJS that we're going to make changes to $scope
    $timeout(function(){
      $scope.imageProfile = snapshot.val().Image;
      console.log(snapshot.val())
    });
  }, function (errorObject) {
    console.log("The read failed: " + errorObject.code);
  })
})

Now with the $firebaseObject...

The $firebaseObject didnt even work for my Simpler version of the plunker as when i put in this code:

$scope.image = $firebaseObject(ref.child('Image'));

It gave me a blank picture... meaning the default picture when the url is not right... And i have noticed that the problem with that is when i console.log() the $scope.image like this:

console.log($scope.image)

I get an object... not a value.. The object is like this:

 $$conf: Object
$id: "Image"
$priority: null
$value: "http://png.clipart.me/graphics/thumbs/151/man-avatar-profile-picture-vector_151265384.jpg"
__proto__: Object

Help would be appreciated in either methods

EDIT 4:

Ok so now i managed to get the Image (The simple plunker i showed you) on the plunker... Here is the code for that:

var obj = $firebaseObject(ref);
obj.$loaded(
  function(data) {
    $scope.image = data.Image
  },
  function(error) {
    console.error("Error:", error);
  }
);

But again when i tried to do that on my actuall app im working on it still dosent work!!! This is my code on the app im working on...:

ref.onAuth(function(authData){
    var obj = $firebaseObject(ref.child("UsersAuthInfo").child(authData.uid));
    obj.$loaded(
    function(data) {
      $scope.imageProfile = data.Image
      console.log(data.Image)
    },
    function(error) {
      console.error("Error:", error);
    }
  );
})

Help would be appreciated!

amanuel2
  • 4,268
  • 2
  • 29
  • 61

1 Answers1

2

Firebase loads the data asynchronously, which is why you have to attach a callback function:

ref.onAuth(function(authData) {
  ref.child("Users Auth Info").child(authData.uid).on("value", function(snapshot) {
    $scope.usernameProfile = snapshot.val().Username;
    $scope.imageProfile = snapshot.val().Image
  })
})

The problem is that by the time your callback is executed, AngularJS is not listening for changes anymore. So your console.log statement probably write out the values fine, the new values are bound to $scope, but AngularJS is simply not updating the views.

This can be fixed, by telling AngularJS that is needs to update the view in its next update cycle:

ref.onAuth(function(authData) {
  ref.child("Users Auth Info").child(authData.uid).on("value", function(snapshot) {
    $timeout(function() {
      $scope.usernameProfile = snapshot.val().Username;
      $scope.imageProfile = snapshot.val().Image
    });
  })
})

Alternatively, you can use AngularFire to accomplish the same.

For a longer explanation and a list of related questions, see Asynchronous access to an array in Firebase

Update

Your minimal code from the Plunkr is:

var ref = new Firebase('https://angularfireauthtut.firebaseio.com/')
  $timeout(function(){
    ref.child('Image').on("value", function(snapshot) {
    console.log(snapshot.val());
    $scope.image = snapshot.val();
  }, function (errorObject) {
    console.log("The read failed: " + errorObject.code);
  })
})

console.log("For some reason this gets logged first?")
console.log($scope.image)

For any next question, make that the only code in your question and we can get somewhere faster.

There are two problems in here, one is visible in the output from console.log(snapshot.val());:

'http://png.clipart.me/graphics/thumbs/151/man-avatar-profile-picture-vector_151265384.jpg'

See those single quotes around there? Those are not supposed to be there, because your HTML now ends up like this:

<img src="'http://png.clipart.me/graphics/thumbs/151/man-avatar-profile-picture-vector_151265384.jpg''" />

The src is surrounded by both double quotes and then single quotes and this means it's not a valid URL anymore.

The proper solution is to store the image without the single quotes. But for now, this will also work:

var imgUrl = snapshot.val();
imgUrl = imgUrl.substring(1, imgUrl.length-1);
$scope.image = imgUrl;

The second problem is that you fail to alert AngularJS of the new image. You've put the $timeout on the wrong level, it needs to be inside the value callback:

ref.child('Image').on("value", function(snapshot) {
  // tell AngularJS that we're going to make changes to $scope
  $timeout(function(){
    var imgUrl = snapshot.val();
    imgUrl = imgUrl.substring(1, imgUrl.length-1);
    console.log(imgUrl);
    $scope.image = imgUrl;
  });
}, function (errorObject) {
  console.log("The read failed: " + errorObject.code);
})

This snippet works and shows your image.

Once you fix the data to not have the single quotes around the Image value anymore, you can get rid of most of this plumbing by using AngularFire:

var ref = new Firebase('https://angularfireauthtut.firebaseio.com/');
$scope.image = $firebaseObject(ref.child('Image'));

I highly recommend that you use that library. But if you don't, read up on $timeout() and AngularFire's digest loop before continuing. Just copying my working snippet without learning about those is guaranteed to lead to an equally frustrating experience soon again.

update for EDIT3

Since your database contains just strings, you'll need to use this in your HTML:

<img ng-src="{{image.$value}}"/>

Updated working plunkr: http://plnkr.co/edit/NlDsxdCqUSboZci6T7ES?p=preview

Community
  • 1
  • 1
Frank van Puffelen
  • 418,229
  • 62
  • 649
  • 645
  • Did you consider what you can do to make it easier for us to help you? Can you reproduce your problem in a *minimal* jsfiddle/jsbin? That will make it more likely that someone is willing to have another look. – Frank van Puffelen Feb 21 '16 at 16:23
  • So minimize the code needed to reproduce the problem and create a jsfiddle. Don't just dump your code in there, spend time to isolate the problem. That means that both you gain a better understanding of the problem and it minimizes the effort you require from those who are trying to help you. See http://stackoverflow.com/help/mcve – Frank van Puffelen Feb 21 '16 at 16:36
  • Good start. Now minimize the code in there. I doubt the `authWithPassword()` and `onAuth()` bits matters, so create the same problem without that. Then remove most of the JavaScript/CSS/HTML, because they likely have nothing to do with the problem either. The recipe is really there in http://stackoverflow.com/help/mcve. – Frank van Puffelen Feb 21 '16 at 16:54
  • I'll add one more update, but then I've done as much as I can here. I understand that you're making quite a journey, but I cannot make it with you any further. You'll have to *read* the documentation and do what it says there. `console.log($scope.image)` is not the way to debug AngularFire, which is why we say to in [step 2 of the programming guide](https://www.firebase.com/docs/web/libraries/angular/guide/synchronized-objects.html). – Frank van Puffelen Feb 21 '16 at 18:52
  • It works now Frank!! I just messud up on the Html!! Thanks a lot Your the best person alive!!! – amanuel2 Feb 21 '16 at 19:04
  • If you're sorry, do as many have been telling you to do: read the documentation. Start with the [AngularFire quickstart](https://www.firebase.com/docs/web/libraries/angular/quickstart.html) and from there read the entire [AngularFire guide](https://www.firebase.com/docs/web/libraries/angular/guide/). Stop doing your project, until you've completed the documentation. – Frank van Puffelen Feb 21 '16 at 19:06
  • Ok Frank! Ill complete the Guide and QuickStart!! – amanuel2 Feb 21 '16 at 19:07