4 * Promise wrapper for OpenSRF network calls.
5 * http://docs.angularjs.org/api/ng.$q
7 * promise.notify() is called with each streamed response.
9 * promise.resolve() is called when the request is complete
10 * and passes as its value the response received from the
11 * last call to onresponse(). If no calls to onresponse()
12 * were made (i.e. no responses delivered) no value will
13 * be passed to resolve(), hence any value seen by the client
14 * will be 'undefined'.
16 * Example: Call with one response and no error checking:
18 * egNet.request(service, method, param1, param2).then(
20 * // data == undefined if no responses were received
21 * // data == null if last response was a null value
25 * Example: capture streaming responses, error checking
27 * egNet.request(service, method, param1, param2).then(
28 * function(data) { console.log('all done') },
29 * function(err) { console.log('error: ' + err) },
30 * functoin(data) { console.log('received stream response ' + data) }
34 angular.module('egCoreMod')
37 ['$q','$rootScope','egEvent',
38 function($q, $rootScope, egEvent) {
42 // Simple container class for tracking a single request.
43 function NetRequest(kwargs) {
45 angular.forEach(kwargs, function(val, key) { self[key] = val });
48 // Relay response object to the caller for typical/successful responses.
49 // Applies special handling to response events that require global
51 net.handleResponse = function(request) {
52 request.evt = egEvent.parse(request.last);
56 if (request.evt.textcode == 'NO_SESSION') {
57 $rootScope.$broadcast('egAuthExpired');
58 request.deferred.reject();
61 } else if (request.evt.textcode == 'PERM_FAILURE') {
63 if (!net.handlePermFailure) {
64 // nothing we can do, pass the failure up to the caller.
65 console.debug("egNet has no handlePermFailure()");
66 request.deferred.notify(request.last);
70 // handlePermFailure() starts a new series of promises.
71 // Tell our in-progress promise to resolve, etc. along
72 // with the new handlePermFailure promise.
73 request.superseded = true;
74 net.handlePermFailure(request).then(
75 request.deferred.resolve,
76 request.deferred.reject,
77 request.deferred.notify
82 request.deferred.notify(request.last);
85 net.request = function(service, method) {
86 var params = Array.prototype.slice.call(arguments, 2);
88 var request = new NetRequest({
92 deferred : $q.defer(),
96 console.debug('egNet ' + method);
97 new OpenSRF.ClientSession(service).request({
99 method : request.method,
100 params : request.params,
101 oncomplete : function() {
102 if (!request.superseded)
103 request.deferred.resolve(request.last);
105 onresponse : function(r) {
106 request.last = r.recv().content();
107 net.handleResponse(request);
109 onerror : function(msg) {
110 // 'msg' currently tells us very little, so don't
111 // bother JSON-ifying it, since there is the off
112 // chance that JSON-ification could fail, e.g if
113 // the object has circular refs.
114 console.error(request.method +
115 ' (' + request.params + ') failed. See server logs.');
116 deferred.reject(msg);
118 onmethoderror : function(req, statCode, statMsg) {
119 console.error('error calling method ' +
120 request.method + ' : ' + statCode + ' : ' + statMsg);
125 return request.deferred.promise;
128 // In addition to the service and method names, accepts a single array
129 // as the collection of API call parameters. This array will get
130 // expanded to individual arguments in the final server call.
131 // This is useful when the server call expects each param to be
132 // a top-level value, but the set of params is dynamic.
133 net.requestWithParamList = function(service, method, params) {
134 var args = [service, method].concat(params);
135 return net.request.apply(net, args);