diff --git a/src/addon/mod/book/providers/book.ts b/src/addon/mod/book/providers/book.ts index 0078341d6..4f97a6e83 100644 --- a/src/addon/mod/book/providers/book.ts +++ b/src/addon/mod/book/providers/book.ts @@ -153,9 +153,9 @@ export class AddonModBookProvider { return promise.then((url) => { // Fetch the URL content. - const observable = this.http.get(url); + const promise = this.http.get(url).toPromise(); - return this.utils.observableToPromise(observable).then((response: Response): any => { + return promise.then((response: Response): any => { const content = response.text(); if (typeof content !== 'string') { return Promise.reject(null); diff --git a/src/classes/site.ts b/src/classes/site.ts index 682561a4e..330b59ea3 100644 --- a/src/classes/site.ts +++ b/src/classes/site.ts @@ -689,13 +689,13 @@ export class CoreSite { * @return {Promise} Promise resolved with the WS response. */ protected getFromCache(method: string, data: any, preSets: CoreSiteWSPreSets, emergency?: boolean): Promise { - const id = this.getCacheId(method, data); - let promise; - if (!this.db || !preSets.getFromCache) { return Promise.reject(null); } + const id = this.getCacheId(method, data); + let promise; + if (preSets.getCacheUsingCacheKey || (emergency && preSets.getEmergencyCacheUsingCacheKey)) { promise = this.db.getRecords(this.WS_CACHE_TABLE, { key: preSets.cacheKey }).then((entries) => { if (!entries.length) { @@ -751,36 +751,37 @@ export class CoreSite { * @return {Promise} Promise resolved when the response is saved. */ protected saveToCache(method: string, data: any, response: any, preSets: CoreSiteWSPreSets): Promise { - const id = this.getCacheId(method, data), - entry: any = { - id: id, - data: JSON.stringify(response) - }; - let cacheExpirationTime = CoreConfigConstants.cache_expiration_time, - promise; - if (!this.db) { return Promise.reject(null); + } + + let promise; + + if (preSets.uniqueCacheKey) { + // Cache key must be unique, delete all entries with same cache key. + promise = this.deleteFromCache(method, data, preSets, true).catch(() => { + // Ignore errors. + }); } else { - if (preSets.uniqueCacheKey) { - // Cache key must be unique, delete all entries with same cache key. - promise = this.deleteFromCache(method, data, preSets, true).catch(() => { - // Ignore errors. - }); - } else { - promise = Promise.resolve(); + promise = Promise.resolve(); + } + + return promise.then(() => { + const id = this.getCacheId(method, data), + entry: any = { + id: id, + data: JSON.stringify(response) + }; + let cacheExpirationTime = CoreConfigConstants.cache_expiration_time; + + cacheExpirationTime = isNaN(cacheExpirationTime) ? 300000 : cacheExpirationTime; + entry.expirationTime = new Date().getTime() + cacheExpirationTime; + if (preSets.cacheKey) { + entry.key = preSets.cacheKey; } - return promise.then(() => { - cacheExpirationTime = isNaN(cacheExpirationTime) ? 300000 : cacheExpirationTime; - entry.expirationTime = new Date().getTime() + cacheExpirationTime; - if (preSets.cacheKey) { - entry.key = preSets.cacheKey; - } - - return this.db.insertOrUpdateRecord(this.WS_CACHE_TABLE, entry, { id: id }); - }); - } + return this.db.insertOrUpdateRecord(this.WS_CACHE_TABLE, entry, { id: id }); + }); } /** @@ -793,17 +794,17 @@ export class CoreSite { * @return {Promise} Promise resolved when the entries are deleted. */ protected deleteFromCache(method: string, data: any, preSets: CoreSiteWSPreSets, allCacheKey?: boolean): Promise { - const id = this.getCacheId(method, data); - if (!this.db) { return Promise.reject(null); - } else { - if (allCacheKey) { - return this.db.deleteRecords(this.WS_CACHE_TABLE, { key: preSets.cacheKey }); - } else { - return this.db.deleteRecords(this.WS_CACHE_TABLE, { id: id }); - } } + + const id = this.getCacheId(method, data); + + if (allCacheKey) { + return this.db.deleteRecords(this.WS_CACHE_TABLE, { key: preSets.cacheKey }); + } + + return this.db.deleteRecords(this.WS_CACHE_TABLE, { id: id }); } /* @@ -985,9 +986,9 @@ export class CoreSite { return Promise.resolve({ code: 0 }); } - const observable = this.http.post(checkUrl, { service: service }).timeout(CoreConstants.WS_TIMEOUT); + const promise = this.http.post(checkUrl, { service: service }).timeout(CoreConstants.WS_TIMEOUT).toPromise(); - return this.utils.observableToPromise(observable).then((data: any) => { + return promise.then((data: any) => { if (typeof data != 'undefined' && data.errorcode === 'requirecorrectaccess') { if (!retrying) { this.siteUrl = this.urlUtils.addOrRemoveWWW(this.siteUrl); diff --git a/src/providers/lang.ts b/src/providers/lang.ts index 9f4dfd699..5622c64e4 100644 --- a/src/providers/lang.ts +++ b/src/providers/lang.ts @@ -161,7 +161,7 @@ export class CoreLangProvider { return language; }).catch(() => { // User hasn't defined a language. If default language is forced, use it. - if (CoreConfigConstants.forcedefaultlanguage && !CoreConfigConstants.forcedefaultlanguage) { + if (!CoreConfigConstants.forcedefaultlanguage) { return CoreConfigConstants.default_lang; } diff --git a/src/providers/sites.ts b/src/providers/sites.ts index c4ecc8268..4b34327a9 100644 --- a/src/providers/sites.ts +++ b/src/providers/sites.ts @@ -387,9 +387,9 @@ export class CoreSitesProvider { data.service = 'c'; } - const observable = this.http.post(siteUrl + '/login/token.php', data).timeout(CoreConstants.WS_TIMEOUT); + const promise = this.http.post(siteUrl + '/login/token.php', data).timeout(CoreConstants.WS_TIMEOUT).toPromise(); - return this.utils.observableToPromise(observable).catch((error) => { + return promise.catch((error) => { return Promise.reject(error.message); }).then((data: any) => { if (data.errorcode && (data.errorcode == 'enablewsdescription' || data.errorcode == 'requirecorrectaccess')) { @@ -426,9 +426,9 @@ export class CoreSitesProvider { password: password, service: service }, - observable = this.http.post(siteUrl + '/login/token.php', params).timeout(CoreConstants.WS_TIMEOUT); + promise = this.http.post(siteUrl + '/login/token.php', params).timeout(CoreConstants.WS_TIMEOUT).toPromise(); - return this.utils.observableToPromise(observable).then((data: any): any => { + return promise.then((data: any): any => { if (typeof data == 'undefined') { return Promise.reject(this.translate.instant('core.cannotconnect')); } else { diff --git a/src/providers/utils/utils.ts b/src/providers/utils/utils.ts index f482b279d..40044549d 100644 --- a/src/providers/utils/utils.ts +++ b/src/providers/utils/utils.ts @@ -850,26 +850,6 @@ export class CoreUtilsProvider { return mapped; } - /** - * Given an observable, convert it to a Promise that will resolve with the first received value. - * - * @param {Observable} obs The observable to convert. - * @return {Promise} Promise. - */ - observableToPromise(obs: Observable): Promise { - return new Promise((resolve, reject): void => { - const subscription = obs.subscribe((data) => { - // Data received, unsubscribe. - subscription.unsubscribe(); - resolve(data); - }, (error) => { - // Data received, unsubscribe. - subscription.unsubscribe(); - reject(error); - }); - }); - } - /** * Similar to AngularJS $q.defer(). * diff --git a/src/providers/ws.ts b/src/providers/ws.ts index 660887a06..267ac509d 100644 --- a/src/providers/ws.ts +++ b/src/providers/ws.ts @@ -238,9 +238,9 @@ export class CoreWSProvider { siteUrl = preSets.siteUrl + '/lib/ajax/service.php'; - const observable = this.http.post(siteUrl, JSON.stringify(ajaxData)).timeout(CoreConstants.WS_TIMEOUT); + const promise = this.http.post(siteUrl, JSON.stringify(ajaxData)).timeout(CoreConstants.WS_TIMEOUT).toPromise(); - return this.utils.observableToPromise(observable).then((data: any) => { + return promise.then((data: any) => { // Some moodle web services return null. // If the responseExpected value is set then so long as no data is returned, we create a blank object. if (!data && !preSets.responseExpected) { @@ -486,7 +486,7 @@ export class CoreWSProvider { let promise = this.getPromiseHttp('head', url); if (!promise) { - promise = this.utils.observableToPromise(this.commonHttp.head(url).timeout(CoreConstants.WS_TIMEOUT)); + promise = this.commonHttp.head(url).timeout(CoreConstants.WS_TIMEOUT).toPromise(); promise = this.setPromiseHttp(promise, 'head', url); } @@ -503,11 +503,18 @@ export class CoreWSProvider { * @return {Promise} Promise resolved with the response data in success and rejected with CoreWSError if it fails. */ performPost(method: string, siteUrl: string, ajaxData: any, preSets: CoreWSPreSets): Promise { - // Perform the post request. - const observable = this.http.post(siteUrl, ajaxData).timeout(CoreConstants.WS_TIMEOUT); - let promise; + const options = {}; - promise = this.utils.observableToPromise(observable).then((data: any) => { + // This is done because some returned values like 0 are treated as null if responseType is json. + if (preSets.typeExpected == 'number' || preSets.typeExpected == 'boolean' || preSets.typeExpected == 'string') { + // Avalaible values are: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType + options['responseType'] = 'text'; + } + + // Perform the post request. + let promise = this.http.post(siteUrl, ajaxData, options).timeout(CoreConstants.WS_TIMEOUT).toPromise(); + + promise = promise.then((data: any) => { // Some moodle web services return null. // If the responseExpected value is set to false, we create a blank object if the response is null. if (!data && !preSets.responseExpected) { @@ -517,9 +524,35 @@ export class CoreWSProvider { if (!data) { return Promise.reject(this.utils.createFakeWSError('core.serverconnection', true)); } else if (typeof data != preSets.typeExpected) { - this.logger.warn('Response of type "' + typeof data + `" received, expecting "${preSets.typeExpected}"`); + // If responseType is text an string will be returned, parse before returning. + if (typeof data == 'string') { + if (preSets.typeExpected == 'number') { + data = Number(data); + if (isNaN(data)) { + this.logger.warn(`Response expected type "${preSets.typeExpected}" cannot be parsed to number`); - return Promise.reject(this.utils.createFakeWSError('core.errorinvalidresponse', true)); + return Promise.reject(this.utils.createFakeWSError('core.errorinvalidresponse', true)); + } + } else if (preSets.typeExpected == 'boolean') { + if (data === 'true') { + data = true; + } else if (data === 'false') { + data = false; + } else { + this.logger.warn(`Response expected type "${preSets.typeExpected}" is not true or false`); + + return Promise.reject(this.utils.createFakeWSError('core.errorinvalidresponse', true)); + } + } else { + this.logger.warn('Response of type "' + typeof data + `" received, expecting "${preSets.typeExpected}"`); + + return Promise.reject(this.utils.createFakeWSError('core.errorinvalidresponse', true)); + } + } else { + this.logger.warn('Response of type "' + typeof data + `" received, expecting "${preSets.typeExpected}"`); + + return Promise.reject(this.utils.createFakeWSError('core.errorinvalidresponse', true)); + } } if (typeof data.exception !== 'undefined') {