MDL-58310 message: No longer need to supress errors from messaging
[moodle.git] / lib / amd / src / ajax.js
CommitLineData
72f8324e
DW
1// This file is part of Moodle - http://moodle.org/
2//
3// Moodle is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// Moodle is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15
16/**
17 * Standard Ajax wrapper for Moodle. It calls the central Ajax script,
18 * which can call any existing webservice using the current session.
19 * In addition, it can batch multiple requests and return multiple responses.
20 *
21 * @module core/ajax
9bdcf579 22 * @class ajax
72f8324e
DW
23 * @package core
24 * @copyright 2015 Damyon Wiese <damyon@moodle.com>
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
9bdcf579 26 * @since 2.9
72f8324e
DW
27 */
28define(['jquery', 'core/config'], function($, config) {
29
30 /**
31 * Success handler. Called when the ajax call succeeds. Checks each response and
32 * resolves or rejects the deferred from that request.
33 *
9bdcf579
DW
34 * @method requestSuccess
35 * @private
72f8324e
DW
36 * @param {Object[]} responses Array of responses containing error, exception and data attributes.
37 */
38 var requestSuccess = function(responses) {
39 // Call each of the success handlers.
40 var requests = this;
41 var exception = null;
42 var i = 0;
43 var request;
44 var response;
45
46 for (i = 0; i < requests.length; i++) {
47 request = requests[i];
48
49 response = responses[i];
50 // We may not have responses for all the requests.
51 if (typeof response !== "undefined") {
52 if (response.error === false) {
53 // Call the done handler if it was provided.
54 request.deferred.resolve(response.data);
55 } else {
56 exception = response.exception;
57 break;
58 }
59 } else {
60 // This is not an expected case.
61 exception = new Error('missing response');
62 break;
63 }
64 }
65 // Something failed, reject the remaining promises.
66 if (exception !== null) {
67 for (; i < requests.length; i++) {
68 request = requests[i];
69 request.deferred.reject(exception);
70 }
71 }
72 };
73
74 /**
75 * Fail handler. Called when the ajax call fails. Rejects all deferreds.
76 *
9bdcf579
DW
77 * @method requestFail
78 * @private
72f8324e
DW
79 * @param {jqXHR} jqXHR The ajax object.
80 * @param {string} textStatus The status string.
81 */
82 var requestFail = function(jqXHR, textStatus) {
83 // Reject all the promises.
84 var requests = this;
85
86 var i = 0;
87 for (i = 0; i < requests.length; i++) {
88 var request = requests[i];
89
3d6ae65b 90 request.deferred.reject(textStatus);
72f8324e
DW
91 }
92 };
93
94 return /** @alias module:core/ajax */ {
95 // Public variables and functions.
96 /**
97 * Make a series of ajax requests and return all the responses.
9bdcf579
DW
98 *
99 * @method call
c96f55e6 100 * @param {Object[]} requests Array of requests with each containing methodname and args properties.
72f8324e
DW
101 * done and fail callbacks can be set for each element in the array, or the
102 * can be attached to the promises returned by this function.
9bdcf579
DW
103 * @param {Boolean} async Optional, defaults to true.
104 * If false - this function will not return until the promises are resolved.
ba224fb4
DW
105 * @param {Boolean} loginrequired Optional, defaults to true.
106 * If false - this function will call the faster nologin ajax script - but
107 * will fail unless all functions have been marked as 'loginrequired' => false
108 * in services.php
9bdcf579 109 * @return {Promise[]} Array of promises that will be resolved when the ajax call returns.
72f8324e 110 */
ba224fb4 111 call: function(requests, async, loginrequired) {
72f8324e
DW
112 var ajaxRequestData = [],
113 i,
c1ac8e7f
TH
114 promises = [],
115 methodInfo = [],
116 requestInfo = '';
9bdcf579 117
4093d643
DW
118 if (typeof loginrequired === "undefined") {
119 loginrequired = true;
120 }
9bdcf579
DW
121 if (typeof async === "undefined") {
122 async = true;
123 }
72f8324e
DW
124 for (i = 0; i < requests.length; i++) {
125 var request = requests[i];
126 ajaxRequestData.push({
127 index: i,
128 methodname: request.methodname,
129 args: request.args
130 });
131 request.deferred = $.Deferred();
132 promises.push(request.deferred.promise());
133 // Allow setting done and fail handlers as arguments.
134 // This is just a shortcut for the calling code.
135 if (typeof request.done !== "undefined") {
136 request.deferred.done(request.done);
137 }
138 if (typeof request.fail !== "undefined") {
139 request.deferred.fail(request.fail);
140 }
141 request.index = i;
c1ac8e7f
TH
142 methodInfo.push(request.methodname);
143 }
144
145 if (methodInfo.length <= 5) {
146 requestInfo = methodInfo.sort().join();
147 } else {
148 requestInfo = methodInfo.length + '-method-calls';
72f8324e
DW
149 }
150
151 ajaxRequestData = JSON.stringify(ajaxRequestData);
152 var settings = {
153 type: 'POST',
154 data: ajaxRequestData,
155 context: requests,
156 dataType: 'json',
9bdcf579 157 processData: false,
023d6a67
BK
158 async: async,
159 contentType: "application/json"
72f8324e
DW
160 };
161
c1ac8e7f 162 var script = 'service.php';
ba224fb4 163 if (!loginrequired) {
c1ac8e7f 164 script = 'service-nologin.php';
ba224fb4 165 }
c1ac8e7f
TH
166 var url = config.wwwroot + '/lib/ajax/' + script +
167 '?sesskey=' + config.sesskey + '&info=' + requestInfo;
ba224fb4 168
9bdcf579
DW
169 // Jquery deprecated done and fail with async=false so we need to do this 2 ways.
170 if (async) {
c1ac8e7f 171 $.ajax(url, settings)
9bdcf579
DW
172 .done(requestSuccess)
173 .fail(requestFail);
174 } else {
175 settings.success = requestSuccess;
176 settings.error = requestFail;
c1ac8e7f 177 $.ajax(url, settings);
9bdcf579 178 }
72f8324e
DW
179
180 return promises;
181 }
182 };
183});