Search code examples
angularjsfirebasedatatableangularjs-material

Fill Material Design Data Table in AngularJS with Firebase data


I am trying to use this module of AngularJS to create a table with information stored in Firebase. The problem is that I can not get the table populated with the data obtained in Firebase. At the moment of loading the page, the progress bar appears, but when it finishes receiving the Firebase information and the progress bar ends, nothing is shown in the table. It remains as you can see in the following image, it also shows how the information is loaded, since it is being printed by the console.

The table has the following structure:

 <md-table-container>
  <table md-table md-row-select="options.rowSelection" multiple="{{options.multiSelect}}" ng-model="selected" md-progress="promise">
    <thead md-head md-order="query.order" md-on-reorder="cargarPacientes">
    <tr md-row>
      <th md-column md-order-by="nombre"><span>Nombre</span></th>
      <th md-column md-order-by="type"><span>Fecha Nacimiento</span></th>
    </tr>
    </thead>
    <tbody md-body>
    <tr md-row md-select="paciente" md-on-select="logItem" md-auto-select="options.autoSelect" ng-repeat="paciente in pacientes.data | filter: filter.search | orderBy: query.order | limitTo: query.limit : (query.page -1) * query.limit">
      <td md-cell>{{paciente.nombre + " " + paciente.apellido}}</td>
      <td md-cell>{{paciente}}</td>
    </tr>
    </tbody>
  </table>
</md-table-container>

And the code with which I access Firebase to obtain the information is:

$scope.pacientes = cargarPacientes();

  function cargarPacientes() {
    var deferred = $q.defer();
    $scope.promise = deferred.promise;
    let pacientesMostrar = {};
    let pacientes = [];
    let database = firebase.database();
    let pacientesRef = database.ref('pacientes');
    $timeout (function () {
      pacientesRef.once('value').then(function(paciente) {
        paciente.forEach(function (pacienteHijo) {
          let childData = pacienteHijo.val();
          childData['key'] = pacienteHijo.key;
          pacientes.push(childData);
        });
        pacientesMostrar['count'] = pacientes.length;
        pacientesMostrar['data'] = pacientes;
        console.log(pacientesMostrar);
        deferred.resolve();
        return pacientes;
      }, function (error) {
        console.error(error);
        deferred.reject();
      });

    }, 2000);
  };

I am not sure that I am using the promises correctly, nor that I am correctly assigning the information obtained from Firebase to the variable $ scope.patients. You can see the expected behavior in the following demo.


Solution

  • Try

      cargarPacientes().then(function(data){
          $scope.pacientes = data;
      })
    
      function cargarPacientes() {
        var deferred = $q.defer();
        let pacientesMostrar = {};
        let pacientes = [];
        let database = firebase.database();
        let pacientesRef = database.ref('pacientes');
        $timeout (function () {
          pacientesRef.once('value').then(function(paciente) {
            paciente.forEach(function (pacienteHijo) {
              let childData = pacienteHijo.val();
              childData['key'] = pacienteHijo.key;
              pacientes.push(childData);
            });
            pacientesMostrar['count'] = pacientes.length;
            pacientesMostrar['data'] = pacientes;
            console.log(pacientesMostrar);
            deferred.resolve(pacientesMostrar);
    
          }, function (error) {
            console.error(error);
            deferred.reject(error);
          });
    
        }, 2000);
        return deferred.promise
      };
    

    The way you are implementing promise is wrong.

    The promise is something which doesnt happen right away, rather it is asynchronous (may take 1 sec to n secs). So, we return deferred.promise and then assign the resolved values (which will come after n secs) to deferred.resolve(data) and similarly for rejection.

    And then $scope.pacientes is put under then() function