Get Ajax data into Angular grid
Asked Answered
T

2

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>
Tollmann answered 27/2, 2013 at 19:3 Comment(0)
G
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.

Gormley answered 27/2, 2013 at 19:50 Comment(5)
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.Gormley
Can you post the line of code it's pointing to? I don't see a variable named options.Gormley
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.Gormley
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.Tollmann
let us continue this discussion in chatGormley
S
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.

Scrooge answered 6/3, 2013 at 18:13 Comment(0)
G
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.

Gormley answered 27/2, 2013 at 19:50 Comment(5)
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.Gormley
Can you post the line of code it's pointing to? I don't see a variable named options.Gormley
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.Gormley
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.Tollmann
let us continue this discussion in chatGormley

© 2022 - 2024 — McMap. All rights reserved.