Skip to content

Instantly share code, notes, and snippets.

@bbagdad
Last active January 18, 2018 15:29
Show Gist options
  • Save bbagdad/322d7316a4069ea3f69fe105bce75c4c to your computer and use it in GitHub Desktop.
Save bbagdad/322d7316a4069ea3f69fe105bce75c4c to your computer and use it in GitHub Desktop.
if (typeof(SDK) == "undefined") {
SDK = {
__namespace: true
};
}
SDK.WEBAPI = {
_context: function () {
///
/// Private function to the context object.
///
///Context
if (typeof GetGlobalContext != "undefined") {
return GetGlobalContext();
} else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
} else if (typeof parent.Xrm != "undefined") {
return parent.Xrm.Page.context;
} {
throw new Error("Context is not available.");
}
}
},
_getEntity: function(source) {
if(source && source.Xrm && source.Xrm.Page && source.Xrm.Page.data) {
return source.Xrm.Page.data.getEntity()
}
return false;
},
getEntity: function() {
var entity = this._getEntity(window);
if(!entity && frames && frames.length > 0) {
for(var ii = 0; ii < frames.length; ii++) {
entity = this._getEntity(frames[ii]);
if(entity) {
return entity;
}
}
}
},
getId: function() {
var entity = this.getEntity();
if(entity) {
return entity.getId();
}
},
getAttribute: function(fieldName){
var entity = this.getEntity();
if(!entity) {console.error("you are not in an entity form"); return;}
var attributes = entity.getAttributes();
if(!attributes) {console.error("you are not in an entity form"); return;}
var att = attributes.getByName(fieldName);
if(att === null) {
console.info(fieldName, "is either empty or does not exist");
return;
}
return att.getValue();
},
getAllAttributes: function(withValue){
var entity = this.getEntity();
if(!entity) {console.error("you are not in an entity form"); return;}
var attributes = entity.getAttributes();
if(!attributes) {console.error("you are not in an entity form"); return;}
var result = [];
attributes.forEach((val, ind) => {
var str = val.getName();
if(withValue) {
str += `, ${val.getValue()}`;
}
result.push(str);
//console.log(val.getName(), ind);
});
return result;
},
_getClientUrl: function () {
///
/// Private function to return the server URL from the context
///
///String
var clientUrl = this._context().getClientUrl()
return clientUrl;
},
_WebAPIPath: function () {
///
/// Private function to return the path to the REST endpoint.
///
///String
return this._getClientUrl() + "/api/data/v8.2/";
},
_errorHandler: function (req) {
///
/// Private function return an Error object to the errorCallback
///
////// The XMLHttpRequest response that returned an error.
/// ///Error
//Error descriptions come from http://support.microsoft.com/kb/193625
if (req.status == 12029) {
return new Error("The attempt to connect to the server failed.");
}
if (req.status == 12007) {
return new Error("The server name could not be resolved.");
}
var errorText;
try {
errorText = JSON.parse(req.responseText).error.message.value;
} catch (e) {
errorText = req.responseText
}
return new Error("Error : " +
req.status + ": " +
req.statusText + ": " + errorText);
},
_dateReviver: function (key, value) {
///
/// Private function to convert matching string values to Date objects.
///
////// The key used to identify the object property
/// ////// The string value representing a date
/// var a;
if (typeof value === 'string') {
a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));
}
}
return value;
},
_parameterCheck: function (parameter, message) {
///
/// Private function used to check whether required parameters are null or undefined
///
/// The parameter to check;
/// The error message text to include when the error is thrown.
if ((typeof parameter === "undefined") || parameter === null) {
throw new Error(message);
}
},
_stringParameterCheck: function (parameter, message) {
///
/// Private function used to check whether required parameters are null or undefined
///
///The string parameter to check;
/// The error message text to include when the error is thrown.
if (typeof parameter != "string") {
throw new Error(message);
}
},
_callbackParameterCheck: function (callbackParameter, message) {
///
/// Private function used to check whether required callback parameters are functions
///
/// The callback parameter to check;
/// The error message text to include when the error is thrown.
if (typeof callbackParameter != "function") {
throw new Error(message);
}
},
createRecord: function (object, type, successCallback, errorCallback) {
///
/// Sends an asynchronous request to create a new record.
///
////// A JavaScript object with properties corresponding to the Schema name of
/// entity attributes that are valid for create operations.
/// ////// The Schema Name of the Entity type record to create.
/// For an Account record, use "Account"
/// ////// The function that will be passed through and be called by a successful response.
/// This function can accept the returned record as a parameter.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// this._parameterCheck(object, "SDK.WEBAPI.createRecord requires the object parameter.");
this._stringParameterCheck(type, "SDK.WEBAPI.createRecord requires the type parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.createRecord requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.createRecord requires the errorCallback is a function.");
if (type.slice(-1) != "s") {
type = type + "s";
}
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._WebAPIPath() + type), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204) {
var entityUri = this.getResponseHeader("OData-EntityId");
var recordId = entityUri.substring(1 + entityUri.lastIndexOf('('), entityUri.length - 1);
successCallback(recordId);
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send(JSON.stringify(object));
},
retrieveRecord: function (id, type, select, expand, successCallback, errorCallback) {
///
/// Sends an asynchronous request to retrieve a record.
///
////// A String representing the GUID value for the record to retrieve.
/// ////// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
/// ////// A String representing the $select OData System Query Option to control which
/// attributes will be returned. This is a comma separated list of Attribute names that are valid for retrieve.
/// If null all properties for the record will be returned
/// ////// A String representing the $expand OData System Query Option value to control which
/// related records are also returned. This is a comma separated list of of up to 6 entity relationship names
/// If null no expanded related records will be returned.
/// ////// The function that will be passed through and be called by a successful response.
/// This function must accept the returned record as a parameter.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// this._stringParameterCheck(id, "SDK.WEBAPI.retrieveRecord requires the id parameter is a string.");
this._stringParameterCheck(type, "SDK.WEBAPI.retrieveRecord requires the type parameter is a string.");
if (select != null)
this._stringParameterCheck(select, "SDK.WEBAPI.retrieveRecord requires the select parameter is a string.");
if (expand != null)
this._stringParameterCheck(expand, "SDK.WEBAPI.retrieveRecord requires the expand parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.retrieveRecord requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.retrieveRecord requires the errorCallback parameter is a function.");
if (type.slice(-1) != "s") {
type = type + "s";
}
var systemQueryOptions = "";
if (select != null || expand != null) {
systemQueryOptions = "?";
if (select != null) {
var selectString = "$select=" + select;
if (expand != null) {
selectString = selectString + "," + expand;
}
systemQueryOptions = systemQueryOptions + selectString;
}
if (expand != null) {
systemQueryOptions = systemQueryOptions + "&$expand=" + expand;
}
}
var req = new XMLHttpRequest();
req.open("GET", encodeURI(this._WebAPIPath() + type + "(" + id + ")" + systemQueryOptions), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response, SDK.WEBAPI._dateReviver)
successCallback(data);
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send();
},
updateRecord: function (id, object, type, successCallback, errorCallback) {
///
/// Sends an asynchronous request to update a record.
///
////// A String representing the GUID value for the record to retrieve.
/// ////// A JavaScript object with properties corresponding to the Schema Names for
/// entity attributes that are valid for update operations.
/// ////// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
/// ////// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// this._stringParameterCheck(id, "SDK.WEBAPI.updateRecord requires the id parameter.");
this._parameterCheck(object, "SDK.WEBAPI.updateRecord requires the object parameter.");
this._stringParameterCheck(type, "SDK.WEBAPI.updateRecord requires the type parameter.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.updateRecord requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.updateRecord requires the errorCallback is a function.");
if (type.slice(-1) != "s") {
type = type + "s";
}
var req = new XMLHttpRequest();
req.open("PATCH", encodeURI(this._WebAPIPath() + type + "(" + id + ")"), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204 || this.status == 1223) {
successCallback();
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send(JSON.stringify(object));
},
deleteRecord: function (id, type, successCallback, errorCallback) {
///
/// Sends an asynchronous request to delete a record.
///
////// A String representing the GUID value for the record to delete.
/// ////// The Schema Name of the Entity type record to delete.
/// For an Account record, use "Account"
/// ////// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// this._stringParameterCheck(id, "SDK.WEBAPI.deleteRecord requires the id parameter.");
this._stringParameterCheck(type, "SDK.WEBAPI.deleteRecord requires the type parameter.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.deleteRecord requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.deleteRecord requires the errorCallback is a function.");
if (type.slice(-1) != "s") {
type = type + "s";
}
var req = new XMLHttpRequest();
req.open("DELETE", encodeURI(this._WebAPIPath() + type + "(" + id + ")", true));
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204) {
successCallback();
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send();
},
retrieveMultipleRecords: function (type, options, withOdata, successCallback, errorCallback, OnComplete) {
///
/// Sends an asynchronous request to retrieve records.
///
////// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
/// ////// A String representing the OData System Query Options to control the data returned
/// ////// The function that will be passed through and be called for each page of records returned.
/// Each page is 50 records. If you expect that more than one page of records will be returned,
/// this function should loop through the results and push the records into an array outside of the function.
/// Use the OnComplete event handler to know when all the records have been processed.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// ////// The function that will be called when all the requested records have been returned.
/// No parameters are passed to this function.
/// this._stringParameterCheck(type, "SDK.WEBAPI.retrieveMultipleRecords requires the type parameter is a string.");
if (options != null)
this._stringParameterCheck(options, "SDK.WEBAPI.retrieveMultipleRecords requires the options parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.retrieveMultipleRecords requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.retrieveMultipleRecords requires the errorCallback parameter is a function.");
//this._callbackParameterCheck(OnComplete, "SDK.WEBAPI.retrieveMultipleRecords requires the OnComplete parameter is a function.");
if (type.slice(-1) != "s") {
type = type + "s";
}
var optionsString = '';
if (options != null) {
if (options.charAt(0) != "?") {
optionsString = "?" + options;
} else {
optionsString = options;
}
}
var req = new XMLHttpRequest();
req.open("GET", this._WebAPIPath() + type + optionsString, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
if (withOdata)
req.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response, SDK.WEBAPI._dateReviver)
successCallback(data);
OnComplete();
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send();
},
fetchXml: function (type, xml, successCallback, errorCallback) {
this._stringParameterCheck(type, "SDK.WEBAPI.retrieveRecord requires the type parameter is a string.");
this._stringParameterCheck(xml, "SDK.WEBAPI.retrieveRecord requires the xml parameter is a string.");
if (type.slice(-1) != "s") {
type = type + "s";
}
xml = xml.replace(/[\r\t\n]/g, '');
var req = new XMLHttpRequest();
req.open("GET", this._WebAPIPath() + type + "?fetchXml=" + xml, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response, SDK.WEBAPI._dateReviver)
successCallback(data);
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send();
},
createFetchXml: function (entityName, attributes, filters, links, order) {
var fetchXml = "<fetch version='1.0' mapping='logical'>";
fetchXml += "<entity name='" + entityName + "'>";
if (attributes) {
for (var ii = 0, len = attributes.length; ii < len; ii++) {
fetchXml += "<attribute name='" + attributes[ii] + "' />"
}
} else {
fetchXml += "<all-attributes />";
}
if (order) {
fetchXml += "<order attribute='" + order.attribute + "' descending='" + order.descending + "' />";
}
if (filters) {
for (var ii = 0, len = filters.length; ii < len; ii++) {
var filter = filters[ii];
fetchXml += "<filter type='" + filter.type + "'>";
for (var cc = 0, fclen = filter.conditions.length; cc < fclen; cc++) {
var condition = filter.conditions[cc];
fetchXml += "<condition attribute='" + condition.attribute + "' operator='" + condition.operator + "' value='" + condition.value + "'/>";
}
fetchXml += "</filter>";
}
}
if (links) {
for (var ii = 0, len = links.length; ii < len; ii++) {
var link = links[ii];
fetchXml += "<link-entity name='" + link.entityName + "' from='" + link.from + "' to='" + link.to + "' alias='" + link.alias + "' >";
if (link.attributes) {
for (var ii = 0, len = link.attributes.length; ii < len; ii++) {
fetchXml += "<attribute name='" + link.attributes[ii] + "' />"
}
} else {
fetchXml += "<all-attributes />";
}
if (link.filters) {
for (var jj = 0, len = link.filters.length; jj < len; jj++) {
var filter = link.filters[jj];
fetchXml += "<filter type='" + filter.type + "'>";
for (var cc = 0, lfclen = filter.conditions.length; cc < lfclen; cc++) {
var condition = filter.conditions[cc];
fetchXml += "<condition attribute='" + condition.attribute + "' operator='" + condition.operator + "' value='" + condition.value + "'/>";
}
fetchXml += "</filter>";
}
}
fetchXml += "</link-entity>";
}
}
fetchXml += "</entity>";
fetchXml += "</fetch>";
return fetchXml;
},
oneObjCreateFetchXml: function (obj) {
var br = this.__newline;
if (!obj.entityName)
throw new Error("\"entityName\" is required");
var getAttribute = function (obj, key, name) {
var hasAttribute = obj.hasOwnProperty(key);
if (hasAttribute) {
return name + "='" + obj[key] + "' ";
}
return '';
}
var buildLink = function (linkObj) {
var entityName = getAttribute(linkObj, 'entityName', 'name');
var from = getAttribute(linkObj, 'from', 'from');
var to = getAttribute(linkObj, 'to', 'to');
var alias = getAttribute(linkObj, 'alias', 'alias');
var linkType = getAttribute(linkObj, 'linkType', 'link-type');
linkXml = "<link-entity " + entityName + from + to + alias + linkType + ">" + br;
if (Array.isArray(linkObj.attributes)) {
for (var ii = 0, len = linkObj.attributes.length; ii < len; ii++) {
linkXml += "<attribute name='" + linkObj.attributes[ii] + "' />" + br;
}
} else if (linkObj.attributes === true) {
linkXml += "<all-attributes />" + br;
}
if (linkObj.filters) {
for (var jj = 0, lflen = linkObj.filters.length; jj < lflen; jj++) {
var filter = linkObj.filters[jj];
var type = getAttribute(filter, 'type', 'type');
linkXml += "<filter " + type + ">";
for (var cc = 0, lfclen = filter.conditions.length; cc < lfclen; cc++) {
var condition = filter.conditions[cc];
var attribute = getAttribute(condition, 'attribute', 'attribute');
var operator = getAttribute(condition, 'operator', 'operator');
var value = getAttribute(condition, 'value', 'value');
linkXml += "<condition " + attribute + operator + value + "/>" + br;
}
linkXml += "</filter>" + br;
}
}
if (linkObj.links) {
for (var ii = 0, len = linkObj.links.length; ii < len; ii++) {
linkXml += buildLink(linkObj.links[ii]);
}
}
linkXml += "</link-entity>" + br;
return linkXml;
}
var fetchXml = "<fetch version='1.0' mapping='logical' " + getAttribute(obj, "top", "top") + ">" + br;
fetchXml += "<entity name='" + obj.entityName + "'>" + br;
if (Array.isArray(obj.attributes)) {
for (var ii = 0, len = obj.attributes.length; ii < len; ii++) {
fetchXml += "<attribute name='" + obj.attributes[ii] + "' />" + br;
}
} else if (obj.attributes === true) {
fetchXml += "<all-attributes />" + br;
}
if (obj.order) {
fetchXml += "<order attribute='" + obj.order.attribute + "' descending='" + (obj.order.descending === true) + "' />" + br;
}
if (obj.filters) {
for (var ii = 0, flen = obj.filters.length; ii < flen; ii++) {
var filter = obj.filters[ii];
fetchXml += "<filter type='" + filter.type + "'>" + br;
for (var cc = 0, fclen = filter.conditions.length; cc < fclen; cc++) {
var condition = filter.conditions[cc];
fetchXml += "<condition attribute='" + condition.attribute + "' operator='" + condition.operator + "' value='" + condition.value + "'/>" + br;
}
fetchXml += "</filter>" + br;
}
}
if (obj.links) {
for (var ii = 0, len = obj.links.length; ii < len; ii++) {
fetchXml += buildLink(obj.links[ii]);
}
}
fetchXml += "</entity>" + br;
fetchXml += "</fetch>" + br;
return fetchXml;
},
retrieveLookupsRecords: function (type, id, lookupEntity, successCallback, errorCallback) {
///
/// Sends an asynchronous request to retrieve records.
///
////// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
/// ////// A String representing the OData System Query Options to control the data returned
/// ////// The function that will be passed through and be called for each page of records returned.
/// Each page is 50 records. If you expect that more than one page of records will be returned,
/// this function should loop through the results and push the records into an array outside of the function.
/// Use the OnComplete event handler to know when all the records have been processed.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// ////// The function that will be called when all the requested records have been returned.
/// No parameters are passed to this function.
/// this._stringParameterCheck(type, "SDK.WEBAPI.retrieveMultipleRecords requires the type parameter is a string.");
//if (options != null)
// this._stringParameterCheck(options, "SDK.WEBAPI.retrieveMultipleRecords requires the options parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.retrieveMultipleRecords requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.retrieveMultipleRecords requires the errorCallback parameter is a function.");
//this._callbackParameterCheck(OnComplete, "SDK.WEBAPI.retrieveMultipleRecords requires the OnComplete parameter is a function.");
if (type.slice(-1) != "s") {
type = type + "s";
}
var optionsString;
if (options != null) {
if (options.charAt(0) != "?") {
optionsString = "?" + options;
} else {
optionsString = options;
}
}
var req = new XMLHttpRequest();
req.open("GET", this._WebAPIPath() + "$metadata#" + type + "/" + id + "/" + lookupEntity, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
//if(withOdata) req.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var data = JSON.parse(this.response, SDK.WEBAPI._dateReviver)
successCallback(data);
OnComplete();
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send();
},
doUnBoundAction: function (object, type, successCallback, errorCallback) {
///
/// Sends an asynchronous request to create a new record.
///
////// A JavaScript object with properties corresponding to the Schema name of
/// entity attributes that are valid for create operations.
/// ////// The Schema Name of the Entity type record to create.
/// For an Account record, use "Account"
/// ////// The function that will be passed through and be called by a successful response.
/// This function can accept the returned record as a parameter.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// this._parameterCheck(object, "SDK.WEBAPI.createRecord requires the object parameter.");
this._stringParameterCheck(type, "SDK.WEBAPI.createRecord requires the type parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.createRecord requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.createRecord requires the errorCallback is a function.");
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._WebAPIPath() + type), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204 || this.status == 200) {
var data = JSON.parse(this.response, SDK.WEBAPI._dateReviver)
successCallback(data);
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send(JSON.stringify(object));
},
doBoundAction: function (object, type, id, action, successCallback, errorCallback) {
///
/// Sends an asynchronous request to create a new record.
///
////// A JavaScript object with properties corresponding to the Schema name of
/// entity attributes that are valid for create operations.
/// ////// The Schema Name of the Entity type record to create.
/// For an Account record, use "Account"
/// ////// The function that will be passed through and be called by a successful response.
/// This function can accept the returned record as a parameter.
/// ////// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// this._parameterCheck(object, "SDK.WEBAPI.createRecord requires the object parameter.");
this._stringParameterCheck(type, "SDK.WEBAPI.doBoundAction requires the type parameter is a string.");
this._stringParameterCheck(id, "SDK.WEBAPI.doBoundAction requires the id parameter is a string.");
this._stringParameterCheck(action, "SDK.WEBAPI.doBoundAction requires the action parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.WEBAPI.doBoundAction requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.WEBAPI.doBoundAction requires the errorCallback is a function.");
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._WebAPIPath() + type + "(" + id + ")/" + action), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204 || this.status == 200) {
var data = JSON.parse(this.response, SDK.WEBAPI._dateReviver)
successCallback(data);
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send(JSON.stringify(object));
},
batchRequest: function (requests, successCallback, errorCallback) {
if (!requests || !Array.isArray(requests) || requests.length == 0) {
throw new Error("first parameter should be array of requests [{entityName: '', fetchXml: ''}]");
}
var data = [];
var addRequest = function (entityName, fetchXml) {
data.push('--batch_123456');
data.push("Content-Type: application/http");
data.push("Content-Transfer-Encoding:binary");
data.push('');
data.push('GET ' + Xrm.Page.context.getClientUrl() + '/api/data/v8.0/' + entityName + '?fetchXml=' + fetchXml + ' HTTP/1.1');
data.push('Content-Type:application/json;type=entry');
data.push('');
}
requests.forEach(obj => {
if (obj.entityName) {
addRequest(obj.entityName, obj.fetchXml.replace(/[\r\n\t]/g, ''));
}
});
//end of batch
data.push('--batch_123456--');
var payload = data.join('\r\n');
var req = new XMLHttpRequest();
req.open("POST", this._WebAPIPath() + "$batch", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "multipart/mixed;boundary=batch_123456");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var boundary = "--".concat(this.getResponseHeader("Content-Type").split("boundary=")[1]);
var data = [];
var parts = this.response.split(boundary);
var splitter = "\r\n\r\n";
parts.forEach(part => {
if (part.indexOf(splitter) != -1) {
var jsonString = part.split(splitter).pop();
data.push(JSON.parse(jsonString));
}
});
successCallback(data);
} else {
errorCallback(SDK.WEBAPI._errorHandler(this));
}
}
};
req.send(payload);
},
__namespace: true,
__newline: "\r\n"
};
@amenayach
Copy link

amenayach commented Dec 19, 2017

Batch request example:

SDK.WEBAPI.batchRequest([{
			entityName: 'net_coursedetails',
			fetchXml: `
				<fetch version='1.0' mapping='logical'>
					<entity name='net_coursedetail'>
						<attribute name='net_coursedetailid' />
						<attribute name='net_description' />
						<attribute name='net_order' />
						<attribute name='net_isaffected' />
						<attribute name='net_numberofminutes' />
						<attribute name='net_videourl' />
						<attribute name='net_applicationurl' />
						<attribute name='net_type' />
						<attribute name='net_availablewithoutregistration' />
					</entity>
				</fetch>
			`
		}, {
			entityName: 'net_courses',
			fetchXml: `
				<fetch version='1.0' mapping='logical'>
					<entity name='net_course'>
						<all-attributes />
					</entity>
				</fetch>
			`
		}
	], console.info, console.error);

Fetch builder

var attributes = ["net_selfassessmentquestionid",
                  "net_questionar",
                  "net_questionen",
                  "net_order",
                  "net_selfassessmentchoiceid",
                  "net_choicear",
                  "net_choiceen",
                  "net_order",
                  "net_iscorrect"];

SDK.WEBAPI.oneObjCreateFetchXml({
	entityName: "name",
	attributes: attributes
}); 

Fetch example:

var fetchXml = `
<fetch version='1.0' mapping='logical'>
	<entity name='net_certificate'>
        <all-attributes />
        <filter>
	    <condition attribute='new_certificatecode' operator='eq' value='qj7b16einc' />
	</filter>
        <link-entity name='net_courseenrollment' to='new_enrollment' from='net_courseenrollmentid' >
            <attribute name='net_course' alias='courseid' />
            <attribute name='net_trainee' alias='traineeid' /> 
        </link-entity>
	</entity>
</fetch>
`.replace(/[\r\n\t]/g, '');

SDK.WEBAPI.fetchXml("net_certificates", fetchXml, console.info, console.error);

@bbagdad
Copy link
Author

bbagdad commented Jan 18, 2018

Update Example

var fieldsToUpdate = {net_completionpercentage: 50, net_name: "new name"};
var recordIdToUpdate = "5adebd61-de82-4cdb-a59e-fc23c47105ff";
var entityPluralName = "net_courseenrollments";
SDK.WEBAPI.updateRecord(recordIdToUpdate, fieldsToUpdate, entityPluralName, console.info, console.error);

Create Example

var fields = {net_completionpercentage: 50, net_name: "new name" .... };
var entityPluralName = "net_courseenrollments";
SDK.WEBAPI.createRecord(fields , entityPluralName, console.info, console.error);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment