1

I am using AngularJS and Datatables together with a server-side script to obtain data via AJAX.

My controller looks like:

var currentJobId = $stateParams.jobId;
var selectedJobId = $rootScope.currentJob;

if (currentJobId !== selectedJobId) {
    $rootScope.currentJob=$stateParams.jobId;
    var data = {
        id: $stateParams.jobId
    }
    $http.post('http://localhost/angular/scripts/getJob.php', data).success(function (thedata) {
        $scope.job = thedata.information;
        $scope.jobNotes = thedata.notes;
        $scope.jobMaterialUsage = thedata.materialUsage;
        $scope.jobItems = thedata.jobItems;
        $scope.jobSubcontractorCosts = thedata.subcontractorCosts;
        $scope.jobBondMiscCosts = thedata.bondMiscCosts;
        $scope.jobEmployeeTime = thedata.employeeTime;
    });
}

An example table looks like:

<table class="table table-striped table-hover row-links" id="employeeTimeTable" ui-jq="dataTable" ui-options="tableOptions">
    <thead>
        <tr>
            <th>Employee Name</th>
            <th>Total Hours</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="time in jobEmployeeTime" ng-click="goToEmployee(job.id,time.id);">
            <td>{{time.name}}</td>
            <td>{{time.total_minutes}}</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th>Employee Name</th>
            <th>Total Hours</th>
        </tr>
    </tfoot>
</table>

So it is basically seeing if the job id has changed and if it has changed, it makes the ajax call for the new job info - if it has not changed it does nothing. The problem I have is that my table is being initialized with datatables before the data loads when I hit refresh. Navigating away from the page and going back to it initializes datatables correctly, but when going DIRECTLY to the page through URL or refresh it just puts the data at the top of the table while still maintaining "No data available in table" and none of the datatables functions working.

4
  • Are you sure the variables in the conditional currentJobId !== selectedJobId are working as supposed? Consider removing the if (currentJobId !== selectedJobId) { for testing this Commented Jul 21, 2015 at 20:11
  • You should create your own directive to initialize and interact with dataTables and to be able to use it's API properly, or better yet use one that already exists. It is too complex a plugin to simply drop into a ui-jq tag and have no control over it Commented Jul 21, 2015 at 20:18
  • Yes, they are working. In fact, putting a simple $state.go($state.current, {}, {reload: true}); after $scope.jobEmployeeTime = thedata.employeeTime; in the post fixes the issue with refresh (since it is refreshing the view)...but then I run into other issues because of this if I use it as a solution. Commented Jul 21, 2015 at 20:21
  • Also consider using an angular grid system that offers the feature set you want from datatables Commented Jul 21, 2015 at 20:22

1 Answer 1

3

With Angular ui-router you could do it with resolving your backend data before the state controller gets called.

Please have a look at the demo below or in this jsFiddle.

It's with-out datatables but that's probably the easier part to add.

(function() {
'use strict';

angular.module('demoApp', ['ui.router', 'angularSpinner'])
    .run(StartUp)
    .factory('jobsDataService', JobsDataFactory)
    .config(Config);

function JobsDataFactory($http) {
    var backendUrl = 'http://jsonplaceholder.typicode.com';
    
    return {
        get: function(id) {
            return $http.jsonp(backendUrl + '/posts/'+id +'?callback=JSON_CALLBACK')
                .then(function(response) {
                    return response.data;
            });
        }
    };
}

function Config($urlRouterProvider, $stateProvider) {
    $urlRouterProvider.otherwise('/jobs/1');
    
    $stateProvider
        .state('jobs',
               {
                   url: '/jobs/:id',
                   templateUrl: 'partials/post.html',
                   resolve: {
                       job: function(jobsDataService, $stateParams) {
                           console.log($stateParams.id);
                           return jobsDataService.get($stateParams.id);
                       }
                   },
                   controller: function($scope, job) {
                       console.log(job);
                       $scope.job = job;
                   }
               });
}

function StartUp($rootScope){
    // only used for loading spinner
    $rootScope
        .$on('$stateChangeStart', 
            function(event, toState, toParams, fromState, fromParams){ 
                $rootScope.loading = true;
        });

    $rootScope
        .$on('$stateChangeSuccess',
            function(event, toState, toParams, fromState, fromParams){ 
                $rootScope.loading = false;
        });

}
    
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.1/spin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-spinner/0.6.2/angular-spinner.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>

<div ng-app="demoApp">
    <span us-spinner="" ng-if="loading"></span>
    <a href="#" ui-sref='jobs({id: 1})'>job 1</a>
    <a href="#" ui-sref='jobs({id: 2})'>job 2</a>
    <a href="#" ui-sref='jobs({id: 3})'>job 3</a>
    <div ui-view=""></div>
    
    <script type="text/ng-template" id="partials/post.html">
        <p>debug id = {{job.id}}</p>
        <h1>{{job.title}}</h1>
        <p>{{job.body}}</p>
    </script>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.