The $scope variable is missing from the DOM

I've been trying to implement ng-repeat with AngularJS, but I'm having trouble getting the scope result in my DOM. Is there something wrong that anyone can spot? I've spent hours troubleshooting this and no matter what I do, "players" always shows up as null.

Here's my HTML:

<body ng-controller="CoachCtrl" >

<div class="mdl-tabs mdl-js-tabs mdl-js-ripple-effect">
  <div class="mdl-tabs__tab-bar">
      <a href="#coach" class="mdl-tabs__tab is-active">Starks</a>
      <a href="#lannisters-panel" class="mdl-tabs__tab">Lannisters</a>
      <a href="#targaryens-panel" class="mdl-tabs__tab">Targaryens</a>
  </div>

  <div class="mdl-tabs__panel is-active" id="coach" >
    <p>Number of players {{ players.length }}</p>
    <table class="table">
      <tr>
          <th>Firstname
          </th>
          <th>Lastname
          </th>
          <th>Tryout Date
          </th>
      </tr>
      <tr ng-repeat="kid in players" >
          <td>{{ kid.firstname }}
          </td>
          <td>{{ kid.lastname }}
          </td>
          <td>{{ kid.tryout_date }}
          </td>
      </tr>
    </table>
  </div>
</div>

And here's my JavaScript:

'use strict';
 
angular.module('myApp.coach', ['ngRoute', 'firebase'])
 
// Declared route 
.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/coach', {
        templateUrl: 'coach/coach.html',
        controller: 'CoachCtrl'
    });
}])

// Home controller

.controller("CoachCtrl", ["$scope", "$firebaseAuth", "$location",
  function($scope, $firebaseAuth, $location) {
    var ref = new Firebase("https://intense-heat-2545.firebaseio.com");
    var authData = ref.getAuth();
    if(authData){
    console.log("User is "+authData.uid+" and is logged in with "+authData.provider);
    var league = new Firebase("https://intense-heat-2545.firebaseio.com/users/"+authData.uid+"/league");
    league.on("value", function(snapshot){
    console.log("League ID = "+snapshot.val());
    var leagueVal = snapshot.val();
    var playerlist = new Firebase("https://blahblah.firebaseio.com/"+leagueVal+"/players");
    $scope.players = [];
                $scope.players.push({firstname:'John', lastname:'B', tryout_date:'2015-11-30'});
                $scope.players.push({firstname: 'Marty', lastname: 'B', tryout_date: '2015-12-01'});
                playerlist.on("child_added", function(snapshot){
                    //console.log("players ="+snapshot.val());
                    var player = snapshot.val();
                    console.log("Firstname ="+player.firstname);
                    var first = player.firstname;
                    var last = player.lastname;
                    var tyd = player.tryout_date;
                    console.log('player data ='+first+last+tyd);

                    $scope.players.push({ firstname: first, lastname: last, tryout_date: tyd });
                    var len = $scope.players.length;
                    for (var i = 0; i < len; i+=1){
                        if (1 === len){
                            console.log("player name = "+$scope.players[i].firstname);
                        }
                        
                    }
                    
                    console.log("players len ="+$scope.players.length);

                }, function(error){
                    console.log("Error getting player info: "+error.code);
                });
    
    console.log("players ="+$scope.players[1].firstname+" len= "+$scope.players.length);
    
    }, function(error){
    console.log("Erro ="+error.code);
    });
    } else {
    console.log("User is not logged in.");
    $location.path('/signin');
    }

}
]);

Answer №1

There are three important points to consider:

  1. The regular Firebase SDK for Angular does not automatically trigger the $digest cycle.
  2. It is recommended to use $firebaseArray() instead of manually handling arrays.
  3. Utilize resolve() in your router to inject authentication information using $firebaseAuth().$waitForAuth().

-

  var rootRef = new Firebase("https://<my-firebase-app>.firebaseio.com");
  var leagueRef = rootRef.child("users").child(authData.uid).child("league");
  // read it one time
  leagueRef.once('value', function(snap) {
     var leagueVal = snapshot.val();
     var playerList = rootRef.child(leagueVal).child("players");
     // $firebaseArray() will synchronize child events into an array
     // Each update will know how to update $digest as well, which
     // will keep the view updated.
     $scope.players = $firebaseArray(playerList);
  });  

Your controller code would be greatly simplified if you use resolve in the router.

.constant('FBURL', '<my-firebase-app>')

.service('RootRef', ['FBURL', Firebase)

.factory('Auth', function($firebaseAuth, RootRef) {
  return $firebaseAuth(RootRef);
})

.factory('UserLeague', function(RootRef) {
  return function(uid) {
    var leagueRef = RootRef.child("user").child(uid).child("league");
    var deferred = $q.defer();
    leagueRef.once(function(snap) {
      deferred.resolve(snap.val());
    });
    return deferred.promise;
  }
})

.config(function($routeProvider) {
    $routeProvider.when('/coach', {
        templateUrl: 'coach/coach.html',
        controller: 'CoachCtrl',
        resolve: {
          leagueVal: function(UserLeague, Auth) {
            var authData = Auth.$getUser();
            return UserLeague(authData.uid);
          },
          authData: function(Auth) {
            return Auth.$waitForAuth();
          }
        }
    });
})

.controller("CoachCtrl", function($scope, leagueVal, authData, RootRef) {
   // no need to check for a user because authData is injected
   // use the resolved leagueVal to create a ref
   var playerList = RootRef.child(leagueVal).child("players");
   // synchronize the players to an array 
   $scope.players = $firebaseArray(playerList);
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps should I take to ensure my clock stays in sync with my runTime function?

I am developing a mini digital clock project with the ability to mimic a physical clock. The clock is activated by using a power button to switch it on and display the current time. It should also be able to turn off and show an empty screen. However, th ...

Employ the AngularJS Variable only when its ID aligns with another AngularJS Variable

How can I display an image in my ng-repeat statement based on matching IDs? The goal is to show the image where the ng-repeat's ID matches the image object's ID. I am struggling with implementing this feature, here is a pseudo code example of wh ...

Is there a way to streamline this generator without using recursion?

I need to develop a unique value generator that produces values within a specified range. The criteria are: all generated values must be distinct the order of values remains consistent upon each run of the generator each value should be significantly diff ...

What is the process for including id parameters within the URL of an HTML page?

As I work on building a website with ReactJS and webpack, I encounter the need to access URL parameters. One specific challenge I face is creating a universal blog post view page that can be dynamically loaded based on the blog id parameter in the URL. Rat ...

Can you always rely on promises being fulfilled?

Consider a scenario where we have a function named logData to handle HTTP requests and another function called logIntoDatabase. async logIntoDatabase(message) { ... } async logData(request, response) { await logIntoDatabase("something happened"); ...

The function image.getState is not recognized (when trying to implement ol in an Angular project)

I attempted to integrate the code provided in an angular(4) application at the following link: However, I encountered an error every time I tried to launch the browser. To start with, here are my imports (both libraries were locally installed via npm): ...

I keep receiving a JavaScript alert message saying "undefined."

When I try to alert the item_id after giving input in the quantity textbox, I am receiving an undefined JavaScript alert. The code snippet below is not displaying the alert as expected: var item_id=$("#item_"+i).val();alert(item_id); In addition, my mode ...

add before the beginning and after the end

Hi there, I'm trying to figure out how to add before my initial variable and after my last one. This is the code snippet: $pagerT.find('span.page-number:first').append($previousT); $pagerT.find('span.page-number:last').append($n ...

Unable to capture Angular 401 error

My attempts to capture 401 responses from an API have been unsuccessful and quite frustrating. Every time I click on a specific link, the browser console displays a 401 response. My goal is to automatically redirect it to the login page whenever this happ ...

Tips for refreshing CSS following an ajax request

Currently, I am facing an issue with the CSS formatting on my page. I am using Django endless pagination to load content on page scroll. However, when new content is loaded, the CSS applied to the page does not work properly and needs to be refreshed. Can ...

Angular app sends a JSON request and receives no data in response

It seems like Angular may be loading the page before fully receiving all the information from JSONP. There are times when refreshing the page multiple times eventually displays the information, but it's not consistent. Interestingly, the code used on ...

Vue.js Components Facing Build Issues

I am currently experiencing a puzzling phenomenon. While working on my application components using Laravel Jetstream and Inertia Stack with VueJS, I encountered an issue where a newly created component in the same folder as others was not building. Neithe ...

Set the style of the mat-select element

I'm having an issue with my select option in Angular Material. The options look fine, but when I select one, the strong tag disappears. Can anyone help me style only that part? Thank you in advance. <mat-select formControlName="projectId" ...

Is there a way to trigger this pop-up after reaching a certain percentage of the page while scrolling?

I've been working on a WordPress site that features an "article box" which suggests another article to users after they scroll to a certain point on the page. However, the issue is that this point is not relative but absolute. This means that the box ...

Adding External JS Files to a Node.js Project

I recently discovered how to incorporate a JS file into Node JS. However, I am facing an issue with two JS files in particular - hashing.js and encoding.js. Within encoding.js, I have the following code: exports = exports || {}; exports.encoding = encodi ...

In TypeScript, an interface property necessitates another property to be valid

In the scenario where foo is false, how can I designate keys: a, b, c, bar as having an undefined/null/optional type? Put simply, I require these properties to be classified as mandatory only when foo is true. interface ObjectType { foo: boolean; a: nu ...

Is it possible to showcase multiple items in react JS based on logical operators?

How can I update the navigation bar to display different menu options based on the user's login status? When a user is logged in, the "Logout", "Add Product", and "Manage Inventory" options should be shown. If a user is not logged in, only the "Home" ...

Testing the local transmission of form data via Javascript: A Step-by-Step guide

Currently studying how to send forms using JavaScript by manually creating an XMLHttpRequest. Towards the end of the provided example, there's a note: Note: If you want to send data to a third party website, keep in mind that this use of XMLHttpRequ ...

Incorporate a custom style sheet into your Express application

Utilizing ejs, express, and parse.com for my web application backend has presented a challenge when it comes to adding stylesheets. Despite searching for solutions, I have not been able to resolve the issue. Sharing my code in hopes of finding a solution. ...

Displaying the URL of a link on the screen using jQuery

I am looking for a solution to add a link address after the link itself in a table containing reference links for our staff. I have used CSS to achieve this in the past, but the address was not copyable by users. Instead, I am interested in using jQuery&ap ...