blob: 4efeff5613cc80de71e4c4a708e2af096ff2e126 [file] [log] [blame]
jsseidela3b65e42017-09-28 14:31:07 -04001Pulling DB data
2===============
3
4In 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.
5
6AngularJS Promises
7----------------------
8
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:
10
11.. code-block:: javascript
12
13 var p = $http.get("http://somedomain.com/some_request");
14
15 p.success(function(result) {
16 console.log("The web server returned: " + result);
17 });
18
19 p.error(function(response, status) {
20 console.log("The web server returned:\n\tStatus: " + status + "\n\tError: " + response);
21 });
22
23Here, 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.
24
25Data service
26------------
27
28Our 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.
29
30Something like this:
31
32.. code-block:: javascript
33
34 $scope.myFunction = function() {
35 dataService.getSomeData().then(function(rv) {
36 // Do something here.
37 });
38 }
39
40Here, :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.
41
42Technically, 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.
43
44Here is our :code:`data-service.js` code:
45
46.. code-block:: javascript
47
48 appDS2.factory('dataService', function ($http, $q, $log) {
49 return {
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') {
54 return response.data;
55 }
56 else {
57 return $q.reject(response.data);
58 }
59 }, function(response) {
60 return $q.reject(response.data);
61 })
62 }
63 };
64 });
65
66The 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/>`_.
67
68Essentially, our service definition is a super-concise JavaScript way to allow this from within our controller:
69
70.. code-block:: javascript
71
72 dataService.getChartData(direction).then(function(rv) {
73 // Do something here
74 });
75
76Behind the scenes, this makes an :code:`HTTP` request that looks like this:
77
78:code:`http://localhost:8080/epsdk-app-os/get_chart_data/<direction>/`
79
80where :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.
81
82Modifying our Spring controller
83-------------------------------
84
85Let's add a couple of functions to our Spring controller, :code:`MyAppController.java`:
86
87.. code-block:: java
88
89 @RequestMapping(value = {"/get_chart_data/{direction}/"}, method = RequestMethod.GET)
90 public void getChartData(@PathVariable("direction") String direction, HttpServletRequest request, HttpServletResponse response){
91 try {
92 Object a = _getChartData(direction);
93 response.getWriter().write(a.toString());
94 } catch (IOException e) {
95 // Probably should do something here ;-)
96 }
97 }
98
99 private Object _getChartData(String direction) {
100 ArrayList<JSONObject> allData = new ArrayList<JSONObject>();
101 JdbcTemplate jdbcTempl = new JdbcTemplate(m_dataSources.get("myappdb"));
102
103 // Check our parameter
104 if (!direction.equals("download") && !direction.equals("upload"))
105 direction = "download";
106 }
107
108 String query = "select data_date, speedmbps, direction from mock_data_avg_speed where direction='" + direction + "' order by data_date asc";
109
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"));
116 allData.add(jo);
117 }
118
119 return allData;
120 }
121
122Testing our changes
123-------------------
124
125To test our database connection, first compile and install the war as in the :ref:`installingyourapp` section. Next, `login`_. Now try the `following URL`_:
126
127::
128
129 http://localhost:8080/epsdk-app-os/get_chart_data/download/
130
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.
132
133If everything went as planned, you should see:
134
135::
136
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"}]
138
139This 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.
140
141.. _following URL: http://localhost:8080/epsdk-app-os/get_chart_data/download/
142.. _login: http://localhost:8080/epsdk-app-os/login.htm