d2
Version:
Javascript library for DHIS2
554 lines (477 loc) • 41.7 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>api/Api.js - Documentation</title>
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
<div class="navicon"></div>
</label>
<label for="nav-trigger" class="overlay"></label>
<nav >
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="GeoFeatures.html">GeoFeatures</a></li><li></li><li><a href="module-analytics.Analytics.html">Analytics</a><ul class='methods'><li data-type='method'><a href="module-analytics.Analytics.html#.getAnalytics">getAnalytics</a></li></ul></li><li><a href="module-analytics.AnalyticsAggregate.html">AnalyticsAggregate</a><ul class='methods'><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#get">get</a></li><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#getDataValueSet">getDataValueSet</a></li><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#getDebugSql">getDebugSql</a></li><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#getRawData">getRawData</a></li></ul></li><li><a href="module-analytics.AnalyticsEvents.html">AnalyticsEvents</a><ul class='methods'><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#get">get</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getAggregate">getAggregate</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getCluster">getCluster</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getCount">getCount</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getQuery">getQuery</a></li></ul></li><li><a href="module-analytics.AnalyticsRequest.html">AnalyticsRequest</a><ul class='methods'><li data-type='method'><a href="module-analytics.AnalyticsRequest.html#fromModel">fromModel</a></li></ul></li><li><a href="module-api.Api.html">Api</a><ul class='methods'><li data-type='method'><a href="module-api.Api.html#get">get</a></li><li data-type='method'><a href="module-api.Api.html#patch">patch</a></li><li data-type='method'><a href="module-api.Api.html#post">post</a></li><li data-type='method'><a href="module-api.Api.html#setBaseUrl">setBaseUrl</a></li><li data-type='method'><a href="module-api.Api.html#setDefaultHeaders">setDefaultHeaders</a></li><li data-type='method'><a href="module-api.Api.html#setUnauthorizedCallback">setUnauthorizedCallback</a></li><li data-type='method'><a href="module-api.Api.html#update">update</a></li></ul></li><li><a href="module-current-user.CurrentUser.html">CurrentUser</a><ul class='methods'><li data-type='method'><a href="module-current-user.CurrentUser.html#.create">create</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canCreate">canCreate</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canCreatePrivate">canCreatePrivate</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canCreatePublic">canCreatePublic</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canDelete">canDelete</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canUpdate">canUpdate</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getDataViewOrganisationUnits">getDataViewOrganisationUnits</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getOrganisationUnits">getOrganisationUnits</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getUserGroupIds">getUserGroupIds</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getUserGroups">getUserGroups</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getUserRoles">getUserRoles</a></li></ul></li><li><a href="module-current-user.UserAuthorities.html">UserAuthorities</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserAuthorities.html#.create">create</a></li><li data-type='method'><a href="module-current-user.UserAuthorities.html#has">has</a></li></ul></li><li><a href="module-current-user.UserDataStore.html">UserDataStore</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserDataStore.html#.getUserDataStore">getUserDataStore</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#create">create</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#delete">delete</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#get">get</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#getAll">getAll</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#has">has</a></li></ul></li><li><a href="module-current-user.UserDataStoreNamespace.html">UserDataStoreNamespace</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#delete">delete</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#get">get</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#getKeys">getKeys</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#set">set</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#update">update</a></li></ul></li><li><a href="module-current-user.UserSettings.html">UserSettings</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserSettings.html#all">all</a></li><li data-type='method'><a href="module-current-user.UserSettings.html#get">get</a></li><li data-type='method'><a href="module-current-user.UserSettings.html#set">set</a></li></ul></li><li><a href="module-datastore.DataStore.html">DataStore</a><ul class='methods'><li data-type='method'><a href="module-datastore.DataStore.html#.getDataStore">getDataStore</a></li><li data-type='method'><a href="module-datastore.DataStore.html#create">create</a></li><li data-type='method'><a href="module-datastore.DataStore.html#delete">delete</a></li><li data-type='method'><a href="module-datastore.DataStore.html#get">get</a></li><li data-type='method'><a href="module-datastore.DataStore.html#getAll">getAll</a></li><li data-type='method'><a href="module-datastore.DataStore.html#has">has</a></li></ul></li><li><a href="module-datastore.DataStoreNamespace.html">DataStoreNamespace</a><ul class='methods'><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#delete">delete</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#get">get</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#getKeys">getKeys</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#getMetaData">getMetaData</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#set">set</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#update">update</a></li></ul></li><li><a href="module-i18n-I18n.html">I18n</a><ul class='methods'><li data-type='method'><a href="module-i18n-I18n.html#.getI18n">getI18n</a></li><li data-type='method'><a href="module-i18n-I18n.html#addSource">addSource</a></li><li data-type='method'><a href="module-i18n-I18n.html#addStrings">addStrings</a></li><li data-type='method'><a href="module-i18n-I18n.html#getTranslation">getTranslation</a></li><li data-type='method'><a href="module-i18n-I18n.html#getUntranslatedStrings">getUntranslatedStrings</a></li><li data-type='method'><a href="module-i18n-I18n.html#isTranslated">isTranslated</a></li><li data-type='method'><a href="module-i18n-I18n.html#load">load</a></li></ul></li><li><a href="module-model.Filter.html">Filter</a><ul class='methods'><li data-type='method'><a href="module-model.Filter.html#.getFilter">getFilter</a></li><li data-type='method'><a href="module-model.Filter.html#equals">equals</a></li><li data-type='method'><a href="module-model.Filter.html#ilike">ilike</a></li><li data-type='method'><a href="module-model.Filter.html#in">in</a></li><li data-type='method'><a href="module-model.Filter.html#like">like</a></li><li data-type='method'><a href="module-model.Filter.html#notEqual">notEqual</a></li><li data-type='method'><a href="module-model.Filter.html#notIn">notIn</a></li><li data-type='method'><a href="module-model.Filter.html#nToken">nToken</a></li><li data-type='method'><a href="module-model.Filter.html#on">on</a></li><li data-type='method'><a href="module-model.Filter.html#operator">operator</a></li><li data-type='method'><a href="module-model.Filter.html#token">token</a></li></ul></li><li><a href="module-model.Filters.html">Filters</a><ul class='methods'><li data-type='method'><a href="module-model.Filters.html#.getFilters">getFilters</a></li><li data-type='method'><a href="module-model.Filters.html#getFilterList">getFilterList</a></li><li data-type='method'><a href="module-model.Filters.html#getFilters">getFilters</a></li><li data-type='method'><a href="module-model.Filters.html#getQueryFilterValues">getQueryFilterValues</a></li><li data-type='method'><a href="module-model.Filters.html#list">list</a></li><li data-type='method'><a href="module-model.Filters.html#logicMode">logicMode</a></li><li data-type='method'><a href="module-model.Filters.html#on">on</a></li></ul></li><li><a href="module-model.Model.html">Model</a><ul class='methods'><li data-type='method'><a href="module-model.Model.html#.create">create</a></li></ul></li><li><a href="module-model.ModelBase.html">ModelBase</a><ul class='methods'><li data-type='method'><a href="module-model.ModelBase.html#create">create</a></li><li data-type='method'><a href="module-model.ModelBase.html#delete">delete</a></li><li data-type='method'><a href="module-model.ModelBase.html#getCollectionChildren">getCollectionChildren</a></li><li data-type='method'><a href="module-model.ModelBase.html#getCollectionChildrenPropertyNames">getCollectionChildrenPropertyNames</a></li><li data-type='method'><a href="module-model.ModelBase.html#getDirtyChildren">getDirtyChildren</a></li><li data-type='method'><a href="module-model.ModelBase.html#getDirtyPropertyNames">getDirtyPropertyNames</a></li><li data-type='method'><a href="module-model.ModelBase.html#getEmbeddedObjectCollectionPropertyNames">getEmbeddedObjectCollectionPropertyNames</a></li><li data-type='method'><a href="module-model.ModelBase.html#getReferenceProperties">getReferenceProperties</a></li><li data-type='method'><a href="module-model.ModelBase.html#hasDirtyChildren">hasDirtyChildren</a></li><li data-type='method'><a href="module-model.ModelBase.html#isDirty">isDirty</a></li><li data-type='method'><a href="module-model.ModelBase.html#resetDirtyState">resetDirtyState</a></li><li data-type='method'><a href="module-model.ModelBase.html#save">save</a></li><li data-type='method'><a href="module-model.ModelBase.html#toJSON">toJSON</a></li><li data-type='method'><a href="module-model.ModelBase.html#validate">validate</a></li></ul></li><li><a href="module-model.ModelCollection.html">ModelCollection</a><ul class='methods'><li data-type='method'><a href="module-model.ModelCollection.html#add">add</a></li><li data-type='method'><a href="module-model.ModelCollection.html#clear">clear</a></li><li data-type='method'><a href="module-model.ModelCollection.html#toArray">toArray</a></li></ul></li><li><a href="module-model.ModelCollectionProperty.html">ModelCollectionProperty</a><ul class='methods'><li data-type='method'><a href="module-model.ModelCollectionProperty.html#.create">create</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#add">add</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#isDirty">isDirty</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#remove">remove</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#resetDirtyState">resetDirtyState</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#save">save</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#updateDirty">updateDirty</a></li></ul></li><li><a href="module-model.ModelDefinition.html">ModelDefinition</a><ul class='methods'><li data-type='method'><a href="module-model.ModelDefinition.html#.createFromSchema">createFromSchema</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#create">create</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#delete">delete</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#get">get</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#getOwnedPropertyNames">getOwnedPropertyNames</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#getTranslatableProperties">getTranslatableProperties</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#getTranslatablePropertiesWithKeys">getTranslatablePropertiesWithKeys</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#isTranslatable">isTranslatable</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#list">list</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#save">save</a></li></ul></li><li><a href="module-model.ModelDefinitions.html">ModelDefinitions</a><ul class='methods'><li data-type='method'><a href="module-model.ModelDefinitions.html#add">add</a></li><li data-type='method'><a href="module-model.ModelDefinitions.html#mapThroughDefinitions">mapThroughDefinitions</a></li></ul></li><li><a href="module-model.ModelValidation.html">ModelValidation</a><ul class='methods'><li data-type='method'><a href="module-model.ModelValidation.html#.getModelValidation">getModelValidation</a></li><li data-type='method'><a href="module-model.ModelValidation.html#validate">validate</a></li><li data-type='method'><a href="module-model.ModelValidation.html#validateAgainstSchema">validateAgainstSchema</a></li></ul></li><li><a href="module-model.Pager.html">Pager</a><ul class='methods'><li data-type='method'><a href="module-model.Pager.html#getNextPage">getNextPage</a></li><li data-type='method'><a href="module-model.Pager.html#getPreviousPage">getPreviousPage</a></li><li data-type='method'><a href="module-model.Pager.html#goToPage">goToPage</a></li><li data-type='method'><a href="module-model.Pager.html#hasNextPage">hasNextPage</a></li><li data-type='method'><a href="module-model.Pager.html#hasPreviousPage">hasPreviousPage</a></li></ul></li><li><a href="module-system.System.html">System</a><ul class='methods'><li data-type='method'><a href="module-system.System.html#.compareVersions">compareVersions</a></li><li data-type='method'><a href="module-system.System.html#.getSystem">getSystem</a></li><li data-type='method'><a href="module-system.System.html#.isVersionCompatible">isVersionCompatible</a></li><li data-type='method'><a href="module-system.System.html#.parseVersionString">parseVersionString</a></li><li data-type='method'><a href="module-system.System.html#installAppVersion">installAppVersion</a></li><li data-type='method'><a href="module-system.System.html#loadAppStore">loadAppStore</a></li><li data-type='method'><a href="module-system.System.html#loadInstalledApps">loadInstalledApps</a></li><li data-type='method'><a href="module-system.System.html#reloadApps">reloadApps</a></li><li data-type='method'><a href="module-system.System.html#setInstalledApps">setInstalledApps</a></li><li data-type='method'><a href="module-system.System.html#setSystemInfo">setSystemInfo</a></li><li data-type='method'><a href="module-system.System.html#uninstallApp">uninstallApp</a></li><li data-type='method'><a href="module-system.System.html#uploadApp">uploadApp</a></li></ul></li><li><a href="module-system.SystemConfiguration.html">SystemConfiguration</a><ul class='methods'><li data-type='method'><a href="module-system.SystemConfiguration.html#all">all</a></li><li data-type='method'><a href="module-system.SystemConfiguration.html#get">get</a></li></ul></li><li><a href="module-system.SystemSettings.html">SystemSettings</a><ul class='methods'><li data-type='method'><a href="module-system.SystemSettings.html#all">all</a></li><li data-type='method'><a href="module-system.SystemSettings.html#get">get</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-analytics.html">analytics</a></li><li><a href="module-api.html">api</a></li><li><a href="module-current-user.html">current-user</a></li><li><a href="module-d2.html">d2</a><ul class='members'><li data-type='member'><a href="module-d2.html#.config">config</a></li></ul><ul class='methods'><li data-type='method'><a href="module-d2.html#.getInstance">getInstance</a></li><li data-type='method'><a href="module-d2.html#.getManifest">getManifest</a></li><li data-type='method'><a href="module-d2.html#.init">init</a></li><li data-type='method'><a href="module-d2.html#~getUserSettings">getUserSettings</a></li></ul></li><li><a href="module-datastore.html">datastore</a></li><li><a href="module-i18n.html">i18n</a></li><li><a href="module-lib_check.html">lib/check</a><ul class='methods'><li data-type='method'><a href="module-lib_check.html#.checkDefined">checkDefined</a></li><li data-type='method'><a href="module-lib_check.html#.isValidUid">isValidUid</a></li></ul></li><li><a href="module-lib_utils.html">lib/utils</a><ul class='methods'><li data-type='method'><a href="module-lib_utils.html#.customEncodeURIComponent">customEncodeURIComponent</a></li><li data-type='method'><a href="module-lib_utils.html#.pick">pick</a></li></ul></li><li><a href="module-model.html">model</a></li><li><a href="module-period_generators.html">period/generators</a><ul class='methods'><li data-type='method'><a href="module-period_generators.html#.createPeriodGeneratorsForLocale">createPeriodGeneratorsForLocale</a></li></ul></li><li><a href="module-system.html">system</a></li><li><a href="module-uid.html">uid</a><ul class='methods'><li data-type='method'><a href="module-uid.html#.generateUid">generateUid</a></li><li data-type='method'><a href="module-uid.html#.isValidUid">isValidUid</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="module-d2.init-d2.html">d2</a></li></ul><h3>Tutorials</h3><ul><li><a href="tutorial-FAQ.html">FAQ</a></li><li><a href="tutorial-overview.html">overview</a></li></ul><h3>Global</h3><ul><li><a href="global.html#addDataDimension">addDataDimension</a></li><li><a href="global.html#addDataFilter">addDataFilter</a></li><li><a href="global.html#addDimension">addDimension</a></li><li><a href="global.html#addFilter">addFilter</a></li><li><a href="global.html#addOrgUnitDimension">addOrgUnitDimension</a></li><li><a href="global.html#addOrgUnitFilter">addOrgUnitFilter</a></li><li><a href="global.html#addPeriodDimension">addPeriodDimension</a></li><li><a href="global.html#addPeriodFilter">addPeriodFilter</a></li><li><a href="global.html#byOrgUnit">byOrgUnit</a></li><li><a href="global.html#computeWeekBasedPeriod">computeWeekBasedPeriod</a></li><li><a href="global.html#getAll">getAll</a></li><li><a href="global.html">getGeoFeatures</a></li><li><a href="global.html">isValidDisplayName</a></li><li><a href="global.html">isValidOrgUnit</a></li><li><a href="global.html">isValidOrgUnitGroup</a></li><li><a href="global.html">isValidOrgUnitLevel</a></li><li><a href="global.html">isValidUserOrgUnit</a></li><li><a href="global.html#withAggregateData">withAggregateData</a></li><li><a href="global.html#withAggregationType">withAggregationType</a></li><li><a href="global.html#withApprovalLevel">withApprovalLevel</a></li><li><a href="global.html#withAsc">withAsc</a></li><li><a href="global.html#withBbox">withBbox</a></li><li><a href="global.html#withClusterSize">withClusterSize</a></li><li><a href="global.html#withCollapseDataDimensions">withCollapseDataDimensions</a></li><li><a href="global.html#withColumns">withColumns</a></li><li><a href="global.html#withCoordinateField">withCoordinateField</a></li><li><a href="global.html#withCoordinatesOnly">withCoordinatesOnly</a></li><li><a href="global.html#withDesc">withDesc</a></li><li><a href="global.html#withDisplayProperty">withDisplayProperty</a></li><li><a href="global.html#withEndDate">withEndDate</a></li><li><a href="global.html#withEventStatus">withEventStatus</a></li><li><a href="global.html#withFormat">withFormat</a></li><li><a href="global.html#withHideEmptyColumns">withHideEmptyColumns</a></li><li><a href="global.html#withHideEmptyRows">withHideEmptyRows</a></li><li><a href="global.html#withHierarchyMeta">withHierarchyMeta</a></li><li><a href="global.html#withIgnoreLimit">withIgnoreLimit</a></li><li><a href="global.html#withIncludeClusterPoints">withIncludeClusterPoints</a></li><li><a href="global.html#withIncludeMetadataDetails">withIncludeMetadataDetails</a></li><li><a href="global.html#withIncludeNumDen">withIncludeNumDen</a></li><li><a href="global.html#withInputIdScheme">withInputIdScheme</a></li><li><a href="global.html#withLimit">withLimit</a></li><li><a href="global.html#withMeasureCriteria">withMeasureCriteria</a></li><li><a href="global.html#withOuMode">withOuMode</a></li><li><a href="global.html#withOutputIdScheme">withOutputIdScheme</a></li><li><a href="global.html#withOutputType">withOutputType</a></li><li><a href="global.html#withPage">withPage</a></li><li><a href="global.html#withPageSize">withPageSize</a></li><li><a href="global.html#withParameters">withParameters</a></li><li><a href="global.html#withPath">withPath</a></li><li><a href="global.html#withPreAggregationMeasureCriteria">withPreAggregationMeasureCriteria</a></li><li><a href="global.html#withProgram">withProgram</a></li><li><a href="global.html#withProgramStatus">withProgramStatus</a></li><li><a href="global.html#withRelativePeriodDate">withRelativePeriodDate</a></li><li><a href="global.html#withRows">withRows</a></li><li><a href="global.html#withShowHierarchy">withShowHierarchy</a></li><li><a href="global.html#withSkipData">withSkipData</a></li><li><a href="global.html#withSkipMeta">withSkipMeta</a></li><li><a href="global.html#withSkipRounding">withSkipRounding</a></li><li><a href="global.html#withSortOrder">withSortOrder</a></li><li><a href="global.html#withStage">withStage</a></li><li><a href="global.html#withStartDate">withStartDate</a></li><li><a href="global.html#withTableLayout">withTableLayout</a></li><li><a href="global.html#withUserOrgUnit">withUserOrgUnit</a></li><li><a href="global.html#withValue">withValue</a></li></ul>
</nav>
<div id="main">
<h1 class="page-title">api/Api.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* @module api
*/
import 'isomorphic-fetch'
import { checkType } from '../lib/check'
import { customEncodeURIComponent } from '../lib/utils'
import System from '../system/System'
function getMergeStrategyParam(mergeType = 'REPLACE') {
const system = System.getSystem()
if (system.version && Number(system.version.minor) <= 22) {
return `mergeStrategy=${mergeType}`
}
return `mergeMode=${mergeType}`
}
function getUrl(baseUrl, url) {
// If we are dealing with an absolute url use that instead
if (new RegExp('^(:?https?:)?//').test(url)) {
return url
}
const urlParts = []
if (baseUrl) {
urlParts.push(baseUrl)
}
urlParts.push(url)
return urlParts
.join('/')
.replace(new RegExp('(.(?:[^:]))//+', 'g'), '$1/')
.replace(new RegExp('/$'), '')
}
/**
* @description
* Used for interaction with the dhis2 api.
*
* This class is used as the backbone for d2 and handles all the interaction with the server. There is a singleton
* available to be reused across your applications. The singleton can be grabbed from the d2 instance. The api methods all handle URL-encoding for you, so you can just pass them unencoded strings
*
* ```js
* import { getInstance } from 'd2/lib/d2';
*
* getInstance()
* .then(d2 => {
* const api = d2.Api.getApi() // Returns the Api singleton.
*
* api.get('resources');
* });
* ```
*
* Uses {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API|Fetch} to do network requests.
*
* @memberof module:api
*/
class Api {
/**
* @constructor
*
* @param {Fetch} [fetchImpl] The fetch implementation to use. Can be used to pass a different implementation
* similar to the fetch Api. Will default to `window.fetch` in a browser context.
*/
constructor(fetchImpl) {
// Optionally provide fetch to the constructor so it can be mocked during testing
if (typeof fetchImpl === 'function') {
this.fetch = fetchImpl.bind(
typeof window !== 'undefined' ? window : global
)
} else if (typeof fetch !== 'undefined') {
this.fetch = fetch.bind(
typeof window !== 'undefined' ? window : global
)
} else {
throw new Error(
'Failed to initialise D2 Api: No fetch implementation is available'
)
}
this.baseUrl = '/api'
this.defaultFetchOptions = {
mode: 'cors', // requests to different origins fail
credentials: 'include', // include cookies with same-origin requests
cache: 'default', // See https://fetch.spec.whatwg.org/#concept-request-cache-mode
}
this.defaultHeaders = {
'X-Requested-With': 'XMLHttpRequest',
}
this.unauthorizedCallback = null
}
/**
* Used for setting default headers that should be send with every request.
*
* @example
* const api = Api.getApi();
*
* api.setDefaultHeaders({
* 'x-requested-with': 'XMLHttpRequest', // Make sure the Api does not redirect when authorization is expired.
* });
*
* @param {Object.<string, string>} headers Default headers that should be set on every request.
*/
setDefaultHeaders(headers) {
this.defaultHeaders = headers
}
/**
* When any request encounters a 401 - Unauthorized. This callback is called.
* Useful for when you want an session expiration-handler API-wide.
*
* @param {*} cb - Function to call when any request recieves a 401. Called with the response from the server.
*/
setUnauthorizedCallback(cb) {
if (typeof cb !== 'function') {
throw new Error('Callback must be a function.')
}
this.unauthorizedCallback = cb
}
/**
* Performs a GET request.
*
* @param {string} url The url for the request, should be unencoded. Will return a rejected promise for malformed urls and urls that contain encoded query strings.
* @param {*} data Any data that should be sent with the request. For a GET request these are encoded and turned into
* query parameters. For POST and PUT requests it becomes the body.
* @param {Object.<string, any>} options The request options are passed as options to the fetch request.
* These options are passed as the {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init}
* parameter to the fetch request.
*
* @returns {Promise.<*>} The response body.
*/
get(url, data, options) {
return this.request('GET', getUrl(this.baseUrl, url), data, options)
}
/* eslint-disable complexity */
/**
* Performs a POST request.
*
* @param {string} url The url for the request
* @param {*} data Any data that should be send with the request this becomes the body for the POST request
* @param {Object.<string, any>} options The request options are passed as options to the fetch request.
* These options are passed as the {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init}
* parameter to the fetch request.
*
* @returns {Promise.<*>} The response body.
*/
post(url, data, options = {}) {
const requestUrl = getUrl(this.baseUrl, url)
let payload = data
// Ensure that headers are defined and are treated without case sensitivity
options.headers = new Headers(options.headers || {})
if (data !== undefined) {
if (data.constructor.name === 'FormData') {
// Ensure that the browser will set the correct Content-Type header for FormData, including boundary
options.headers.delete('Content-Type')
payload = data
} else if (
options.headers.has('Content-Type') &&
options.headers
.get('Content-Type')
.toLocaleLowerCase()
.startsWith('text/')
) {
payload = String(data)
} else {
// Send JSON data by default
options.headers.set('Content-Type', 'application/json')
payload = JSON.stringify(data)
}
}
return this.request('POST', requestUrl, payload, options)
}
/**
* Performs a DELETE request.
*
* @param {string} url The url for the request
* @param {Object.<string, any>} options The request options are passed as options to the fetch request.
* These options are passed as the {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init}
* parameter to the fetch request.
*
* @returns {Promise.<*>} The response body.
*/
/* eslint-enable complexity */
delete(url, options) {
return this.request(
'DELETE',
getUrl(this.baseUrl, url),
undefined,
options
)
}
/**
* Perform a PUT request.
*
* @param {string} url The url for the request
* @param {*} data Any data that should be send with the request. This becomes the body of the PUT request.
* @param {boolean} [useMergeStrategy=false]
* @param {Object.<string, any>} options The request options are passed as options to the fetch request.
*
* @returns {Promise.<*>} The response body.
*/
update(url, data, useMergeStrategy = false, options = {}) {
let payload = data
// Ensure that headers are defined and are treated without case sensitivity
const requestOptions = {
...options,
headers: new Headers(options.headers || {}),
}
if (data !== undefined) {
if (
!requestOptions.headers.has('Content-Type') &&
typeof payload === 'string'
) {
requestOptions.headers.set('Content-Type', 'text/plain')
} else {
payload = JSON.stringify(data)
}
}
const urlForUpdate =
useMergeStrategy === true
? `${url}?${getMergeStrategyParam()}`
: url
return this.request(
'PUT',
getUrl(this.baseUrl, urlForUpdate),
payload,
requestOptions
)
}
/**
* Perform a PATCH request.
*
* @param {string} url The url for the request
* @param {*} data Any data that should be send with the request. This becomes the body of the PATCH request.
*
* @returns {Promise.<*>} The response body.
*/
patch(url, data) {
return this.request(
'PATCH',
getUrl(this.baseUrl, url),
JSON.stringify(data)
)
}
/**
* General purpose request function for making http requests.
*
* The more specific functions like `delete`, `post` and `get`, utilize this function to make the requests.
*
* @param {string} method The HTTP request method (e.g. POST/GET/PATCH)
* @param {string} url The url for the request
* @param {*} data Any data that should be send with the request. For a GET request these are turned into
* query parameters. For POST and PUT requests it becomes the body.
* @param {Object.<string, any>} options The request options are passed as options to the fetch request.
* These options are passed as the {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init}
* parameter to the fetch request.
*
* @returns {Promise.<*>} The response body.
*/
/* eslint-disable complexity */
request(method, url, data, options = {}) {
checkType(method, 'string', 'Request type')
checkType(url, 'string', 'Url')
const api = this
let requestUrl = url
let query = ''
if (requestUrl.indexOf('?') !== -1) {
query = requestUrl.substr(requestUrl.indexOf('?') + 1)
requestUrl = requestUrl.substr(0, requestUrl.indexOf('?'))
}
// Encode existing query parameters, since tomcat does not accept unencoded brackets. Throw
// an error if they're already encoded to prevent double encoding.
if (query) {
let decodedURL
try {
decodedURL = decodeURIComponent(query)
} catch (err) {
return Promise.reject(
new Error('Query parameters in URL are invalid')
)
}
const isEncoded = query !== decodedURL
if (isEncoded) {
return Promise.reject(
new Error(
'Cannot process URL-encoded URLs, pass an unencoded URL'
)
)
}
query = customEncodeURIComponent(query)
}
// Transfer filter properties from the data object to the query string
if (data && Array.isArray(data.filter)) {
const encodedFilters = data.filter.map(filter =>
filter.split(':').map(encodeURIComponent).join(':')
)
query = `${query}${
query.length ? '&' : ''
}filter=${encodedFilters.join('&filter=')}`
delete data.filter
}
// When using the GET method, transform the data object to query parameters
if (data && method === 'GET') {
Object.keys(data).forEach(key => {
query =
`${query}${query.length > 0 ? '&' : ''}` +
`${encodeURIComponent(key)}=${encodeURIComponent(
data[key]
)}`
})
}
function getOptions(defaultHeaders, mergeOptions, requestData) {
const resultOptions = Object.assign(
{},
api.defaultFetchOptions,
mergeOptions
)
const headers = new Headers(mergeOptions.headers || {})
Object.keys(defaultHeaders)
.filter(header => !headers.get(header))
.forEach(header => headers.set(header, defaultHeaders[header]))
resultOptions.method = method
// Only set content type when there is data to send
// GET requests and requests without data do not need a Content-Type header
// 0 and false are valid requestData values and therefore should have a content type
if (
resultOptions.method === 'GET' ||
(!requestData && requestData !== 0 && requestData !== false)
) {
headers.delete('Content-Type')
} else if (requestData) {
if (data.constructor.name === 'FormData') {
headers.delete('Content-Type')
} else if (!headers.get('Content-Type')) {
headers.set('Content-Type', 'application/json')
}
resultOptions.body = requestData
}
resultOptions.headers = headers
return resultOptions
}
if (query.length) {
requestUrl = `${requestUrl}?${query}`
}
const requestOptions = getOptions(this.defaultHeaders, options, data)
// If the provided value is valid JSON, return the parsed JSON object. If not, return the raw value as is.
function parseResponseData(value) {
try {
return JSON.parse(value)
} catch (e) {
return value
}
}
return new Promise((resolve, reject) => {
// fetch returns a promise that will resolve with any response received from the server
// It will be rejected ONLY if no response is received from the server, i.e. because there's no internet
this.fetch(requestUrl, requestOptions)
.then(response => {
// If the request failed, response.ok will be false and response.status will be the status code
if (response.ok) {
response
.text()
.then(text => resolve(parseResponseData(text)))
} else {
response.text().then(text => {
const parsedResponseData = parseResponseData(text)
if (response.status === 401) {
const request = {
method,
url,
data,
options,
}
if (this.unauthorizedCallback) {
this.unauthorizedCallback(
request,
parsedResponseData
)
}
}
if (
!process.env ||
process.env.npm_lifecycle_event !== 'test'
) {
// eslint-disable-next-line
console.warn(
`API request failed with status ${response.status} ${response.statusText}\n`,
`Request: ${requestOptions.method} ${requestUrl}`
)
}
reject(parsedResponseData)
})
}
})
.catch(err => {
// It's not usually possible to get much info about the cause of the error programmatically, but
// the user can check the browser console for more info
if (
!process.env ||
process.env.npm_lifecycle_event !== 'test'
) {
console.error('Server connection error:', err) // eslint-disable-line
}
reject(
`Server connection failed for API request: ${requestOptions.method} ${requestUrl}`
)
})
})
}
/* eslint-enable complexity */
/**
* Sets the baseUrl that should be used for the api.
*
* When working against the dhis2 demo instance at {@link https://play.dhis2.org/demo} the
* baseUrl would be set as `https://play.dhis2.org/demo/api`.
*
* This method is used when calling the `d2.init` method with the `baseUrl` config property
* to configure the Api singleton.
*
* @param {string} baseUrl The base url to be used for the API.
*
* @returns {this} Itself for chaining purposes
*/
setBaseUrl(baseUrl) {
checkType(baseUrl, 'string', 'Base url')
this.baseUrl = baseUrl
return this
}
}
/**
* Retrieve the Api singleton or create one.
*
* When called for the first time it creates and Api singleton object.
* Any subsequent calls will return the previously created singleton.
*
* @returns {Api} The Api singleton.
* @memberof module:api~Api
*/
function getApi() {
if (getApi.api) {
return getApi.api
}
return (getApi.api = new Api())
}
Api.getApi = getApi
export default Api
</code></pre>
</article>
</section>
</div>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.6</a> on Thu Nov 18 2021 08:51:53 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>
<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>