4 In the :ref:`connectionjava` section, we set up a connection to the :code:`ecomp_sdk` database. Now, we going to use our AngularJS controller (:code:`controller.js`) and data service (:code:`data-service.js`) to make an HTTP request to our Spring controller (:code:`MyAppController.java`), wait for the results, and map them into a Google Chart.
9 "Promises" are a core feature of AngularJS, and whether you fully understand them or not, you will be using them in your applications. Promises use AJAX (Asynchronous JavaScript and XML -- you can also use JSON). When we make a call to a web server for some data, we don't want our application to become unresponsive while we wait for an answer. Therefore, :code:`$http.get` calls (more in a minute), return a Promise object rather than text from the web server. Then, we make sure that the Promise object does the right thing at the right time by assigning callback functions when the web server either returns results or fails to return a result. Something like this:
11 .. code-block:: javascript
13 var p = $http.get("http://somedomain.com/some_request");
15 p.success(function(result) {
16 console.log("The web server returned: " + result);
19 p.error(function(response, status) {
20 console.log("The web server returned:\n\tStatus: " + status + "\n\tError: " + response);
23 Here, AJAX (via the AngularJS module :code:`$http`) makes a request to :code:`somedomain.com/some_request`. Our JavaScript engine immediately then moves to assign anonymous functions as callbacks for success and error conditions. Then, when the web server finally returns a result, the callbacks are run.
28 Our special function in :code:`data-service.js` uses Promises. We make sure to execute code in the correct order by using the :code:`then` Promise function.
32 .. code-block:: javascript
34 $scope.myFunction = function() {
35 dataService.getSomeData().then(function(rv) {
40 Here, :code:`getSomeData` returns a Promise object. The :code:`then` function tells the JavaScript engine to execute the given anonymous function only after the request has completed.
42 Technically, the :code:`then` function takes two functions as arguments. The first defines what to do upon success, and the second defines what to do upon failure. We omitted the failure argument above.
44 Here is our :code:`data-service.js` code:
46 .. code-block:: javascript
48 appDS2.factory('dataService', function ($http, $q, $log) {
50 // Service to return chart data
51 getChartData: function(direction) {
52 return $http.get("get_chart_data/" + direction + "/").then(function(response) {
53 if (typeof response.data === 'object' || typeof response.data === 'string') {
57 return $q.reject(response.data);
59 }, function(response) {
60 return $q.reject(response.data);
66 The syntax of this function is not immediately obvious unless you are comfortable with JavaScript Promises and Deferreds. For a more complete explanation with examples, check out `this blog post <http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/>`_.
68 Essentially, our service definition is a super-concise JavaScript way to allow this from within our controller:
70 .. code-block:: javascript
72 dataService.getChartData(direction).then(function(rv) {
76 Behind the scenes, this makes an :code:`HTTP` request that looks like this:
78 :code:`http://localhost:8080/epsdk-app-os/get_chart_data/<direction>/`
80 where :code:`direction` is either "upload" or "download" and returns the result back to our controller as JSON text, which we'll convert into a JavaScript object for further processing.
82 Modifying our Spring controller
83 -------------------------------
85 Let's add a couple of functions to our Spring controller, :code:`MyAppController.java`:
89 @RequestMapping(value = {"/get_chart_data/{direction}/"}, method = RequestMethod.GET)
90 public void getChartData(@PathVariable("direction") String direction, HttpServletRequest request, HttpServletResponse response){
92 Object a = _getChartData(direction);
93 response.getWriter().write(a.toString());
94 } catch (IOException e) {
95 // Probably should do something here ;-)
99 private Object _getChartData(String direction) {
100 ArrayList<JSONObject> allData = new ArrayList<JSONObject>();
101 JdbcTemplate jdbcTempl = new JdbcTemplate(m_dataSources.get("myappdb"));
103 // Check our parameter
104 if (!direction.equals("download") && !direction.equals("upload"))
105 direction = "download";
108 String query = "select data_date, speedmbps, direction from mock_data_avg_speed where direction='" + direction + "' order by data_date asc";
110 List<Map<String,Object>> out = jdbcTempl.queryForList(query);
111 for (Map<String,Object> row: out) {
112 JSONObject jo = new JSONObject();
113 jo.put("data_date", row.get("data_date"));
114 jo.put("speedmbps", row.get("speedmbps"));
115 jo.put("direction", row.get("direction"));
125 To test our database connection, first compile and install the war as in the :ref:`installingyourapp` section. Next, `login`_. Now try the `following URL`_:
129 http://localhost:8080/epsdk-app-os/get_chart_data/download/
131 .. note:: Using the trailing '/' character can prevent confusion with AngularJS routing. It might not always be necessary, but it is good practice to use it in this context to prevent headaches later on.
133 If everything went as planned, you should see:
137 [{"speedmbps":40,"data_date":"2017-08-01","direction":"download"}, {"speedmbps":18,"data_date":"2017-08-02","direction":"download"}, {"speedmbps":25,"data_date":"2017-08-03","direction":"download"}, {"speedmbps":48,"data_date":"2017-08-04","direction":"download"}, {"speedmbps":49,"data_date":"2017-08-05","direction":"download"}, {"speedmbps":46,"data_date":"2017-08-06","direction":"download"}, {"speedmbps":35,"data_date":"2017-08-07","direction":"download"}]
139 This is what makes JSON such a powerful tool. We'll take that JSON output and convert it into JavaScript objects in order to build our chart.
141 .. _following URL: http://localhost:8080/epsdk-app-os/get_chart_data/download/
142 .. _login: http://localhost:8080/epsdk-app-os/login.htm