Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to write a simple app that does the following: 1. User inputs 2 parameters & clicks a button 2. Angular calls an external JAVA Servlet that returns JSON 3. App outputs the json string to the screen

I have a problem however, as when i click the button nothing happens. I believe (due to testing) that the reason this happens is that since the call is async, the variable that is returned is null.

Pertinent code:

controllers.js

function myAppController($scope,kdbService) {
    $scope.buttonClick = function(){
        var dat = kdbService.get($scope.tName,$scope.nRows);
        $scope.data = dat;

    }
}

services.js

angular.module('myApp.services', []).factory('kdbService',function ($rootScope,$http){
    var server="http://localhost:8080/KdbRouterServlet";
    return {
        get: function(tname,n){
            var dat;
            $http.jsonp(server+"?query=krisFunc[`"+tname+";"+n+"]&callback=JSON_CALLBACK").
                success(function(data, status, headers, config) {
                    console.log("1");
                    console.log(data);
                    dat=data;
                }).
                error(function(data, status, headers, config) {
                    alert("ERROR: Could not get data.");
                });
            console.log("2");
            console.log(dat);
            return dat;
        }
    }
});

index.html

<!-- Boilerplate-->
<h1>Table Viewer</h1>
<div class="menu" >
    <form>
        <label for="tName">Table Name</label>
        <input id="tName" ng-model="tName"><br>
        <label for="nRows">Row Limit</label>
        <input id="nRows" ng-model="nRows"><br>
        <input type="submit" value="Submit" ng-click="buttonClick()">
    </form>
</div>
{{data}}
<!-- Boilerplate-->

When i execute the code and push the button, nothing happens. However, if i look in my log, i see this:

2
undefined
1 
Object {x: Array[2], x1: Array[2]}

Clearly, what is happening is that the success function returns after the get function has returned. Therefore the object put into $scope.data is undefined, but the object returned from the jsonp call is left behind.

Is there a correct way to be doing this? Most of the tutorials I see assign the data to the $scope variable inside the success function, thereby skipping this problem. I want my service to be detached if possible.

Any help would be appreciated.

share|improve this question
add comment

1 Answer

up vote 5 down vote accepted

i would do something like that :

controller

function myAppController($scope,kdbService) {
    $scope.kdbService = kdbService;
    $scope.buttonClick = function(){
        $scope.kdbService.get($scope.tName,$scope.nRows);

    }
}

service

angular.module('myApp.services', []).factory('kdbService',function ($rootScope,$http){
    var server="http://localhost:8080/KdbRouterServlet";
    return {
        data:{},
        get: function(tname,n){
            var self = this;
            $http.jsonp(server+"?
            query=krisFunc[`"+tname+";"+n+"]&callback=JSON_CALLBACK").
                success(function(data, status, headers, config) {
                    console.log("1");
                    console.log(data);
                    self.data = data;
                }).
                error(function(data, status, headers, config) {
                    alert("ERROR: Could not get data.");
                });
        }
    }
});

html

{{kdbService.data}}

OR

use continuation in the get method :

controller

function myAppController($scope,kdbService) {
    $scope.buttonClick = function(){
        kdbService.get($scope.tName,$scope.nRows,function success(data){
           $scope.data = data;
        });
    }
}

service

    get: function(tname,n,successCallback){
        $http.jsonp(server+"?query=krisFunc[`"+tname+";"+n+"]&callback=JSON_CALLBACK").
            success(function(data, status, headers, config) {
                successCallback(data,status,headers,config);
            }).
            error(function(data, status, headers, config) {
                alert("ERROR: Could not get data.");
            });
    }

OR use the $resource service

http://docs.angularjs.org/api/ngResource.$resource ( you'll need the angular-resource module

code not tested.

I want my service to be detached if possible.

then put the "data object" in a "data service" calling a "data provider service". You'll have to call the "data provider service" somewhere anyway. There is no skipping this problem in my opinion, since that's how javascript work.

also use angular.controller("name",["$scope,"service",function($s,s){}]);

so you will not need to care how parameters are called , as long as they are defined and injected properly.

share|improve this answer
    
Thanks for those. From a glance I like the look of option 2 as it looks easy to implement. I tried to use the resource service earlier, though had trouble finding good tutorials on it's use in this context. –  user103583 Jan 22 '13 at 17:17
1  
UPDATE: Just tried out method 2 with the callback and it works great! Thanks for the help. –  user103583 Jan 23 '13 at 16:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.