20

Using Angular Grid, I get the ajax get data in console.log. But an empty grid.

The console log reads:

[13:56:11.411] now!!
[13:56:11.412] []
[13:56:11.412] now!!
[13:56:11.556]  <there is data returned from console.log(getData); > 

This is the js file.

// main.js
var app = angular.module('myApp', ['ngGrid']);

var getData = [];

function fetchData() {
    var mydata = [];

    $.ajax({
        url:'/url/to/hell',
        type:'GET',
        success: function(data) {

            for(i = 0, j = data.length; i < j; i++) {
                mydata[i] = data[i];
            }
            getData = mydata;
            console.log(getData);
        }
    });    
 }
fetchData();     


app.controller('MyCtrl', function($scope) {    

    console.log('now!!')
    console.log(getData)
    console.log('now!!')

    $scope.myData = getData


    $scope.gridOptions = { 
        data: 'myData',
        showGroupPanel: true
    };
});

New Js file:

// main.js

var app = angular.module('myApp', ['ngGrid']);

app.controller('MyCtrl', function($scope, $http) {          
function fetchData() {
    $http({
        url:'/url/to/hell',
        type:'GET'})
        .success(function(data) {
            $scope.myData = data;       
            $scope.gridOptions = { 
                    data: 'myData',
                    showGroupPanel: true
                };              
        });         
}   
fetchData();    
});

HTML file.

<html ng-app="myApp">
        <head lang="en">
            <meta charset="utf-8">
            <title>Blank Title 3</title>  
            <link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
            <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
            <script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
            <script type="text/javascript" src="../static/js/main.js"></script>
        </head>

        <body ng-controller="MyCtrl">

            <div class="gridStyle" ng-grid="gridOptions"></div>
        </body>
    </html>

2 Answers 2

26

This would be much easier (and more Angular) if you defined a service for your request. Something along these lines:

angular.module('hellServices', ['ngResource'])
  .factory('Hell', function ($resource) {
    return $resource('URL/TO/HELL', {}, {
      query: { method: 'GET' }
    });
  });

Make sure to include it in your app:

var app = angular.module('myApp', ['ngGrid', 'hellServices']);

Then you can get a promise for it in your controller:

app.controller('MyCtrl', function($scope, $http, Hell) {  
$scope.myData = Hell.query();

And then set the grid options to look at the promise for its data (as you already did):

$scope.gridOptions = { 
    data: 'myData',
    showGroupPanel: true
};

If you do this, you don't have to worry about $scope.$apply because it will be handled for you. This is much cleaner and easier to follow. If you still need a callback to modify the data once it's returned from the server, pass a function to the query() function of your service:

...
$scope.myData = Hell.query(function(hell) {
    // code that modifies 'hell'
});

Check out the official docs on Angular Services. The basics are also covered in Step #11 of the official Angular JS tutorial.

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

Comments

13

Your controller is probably accessing the getData array before the .success is finished. You're accessing the variable right away, outside of a promise function, which is initialized to an empty array.

Why don't you try putting the fetchData function into the controller (for now) and storing the getData directly into $scope.myData in the .success? Maybe even initialize the grid right there too? Not sure if you can do that but if you could it would look like this:

app.controller('MyCtrl', function($scope, $http) {  
$scope.myData = '';
$scope.gridOptions = { showGroupPanel: true, data: 'myData' };
function fetchData() {
    setTimeout(function(){  
        $http({
            url:'/url/to/hell',
            type:'GET'})
            .success(function(data) {
                $scope.myData = data;   
                if (!$scope.$$phase) {
                    $scope.$apply();
                }                   
            });         
    }, 3000);       
}   
fetchData();    
});

(source for some of the $scope apply stuff: https://github.com/angular-ui/ng-grid/issues/39)

Also not sure why you're mixing in jQuery .ajax with angular code ($http will do that), and why none of your javascript has a semicolon.

5 Comments

Sorry, updated the code snippet. You just inject it the same way as $scope. $http is a core angular service. If you have a RESTful API you can also use $resource for further abstraction.
Can you post the line of code it's pointing to? I don't see a variable named options.
Try that - sorry. The $scope objects weren't created in time the previous way. So here you have an empty object bound to the grid data, then the data is updated on success.
I have the blank grid frame, thats where I started. But, still no data in the frame. The ajax, now $http is pulling data from a local database.

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.