2

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.

1 Answer 1

7

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.

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

2 Comments

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.
UPDATE: Just tried out method 2 with the callback and it works great! Thanks for the help.

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.