crmfetchkit
v3.3.2
Published
Library for Dynamics CRM that allows the execution of fetchxml-queries via JavaScript
Downloads
7
Readme
Introduction
Browser library that allows the execution of fetchxml-queries via JavaScript for Dynamics CRM using SOAP endpoint.
Like the CrmRestKit.js depdends this framework on the promise concept, but it uses bluebird instead of jQuery to manage the complexity of asynchronous operation.
The code and the idea for this framework bases on the CrmServiceToolkit developed by Daniel Cai.
Topics
Support
Version 3.x
The version 3.x supports Chrome, Firefox and IE9+ and was tested with Dynamics CRM 2013 Online and Dynamics CRM 2015 Online.
Version 3.3.2
Since version 3.3.2 uses the method GetById
and GetByIdSync
the SOAP Retrieve method. This was needed because the old approach to derive the primary attr. base on the entity name is not working for activities (appointment -> activityid
and not appointmentid
).
Furthermore will the GetById
and GetByIdSync
now generate an error in case no record is found with this id. I the previous version the value null
was returned. See integration-test should yield am error in case a record does not exist
.
Version 2.x
The version 2.x supports Chrome, Firefox and IE8+ and was tested with Dynamics CRM 2013 Online.
Documentation
In case the provided samples in this section are not sufficient, please review the integration tests.
GetById
Instead of create a fetchxml query for a very simple query, this method should be used to load an records based on the id.
var accountid = '06887701-2642-4a53-99ba-c24ce1a5688b',
columns = ['name', 'donotfax', 'donotemail', 'createdon'];
CrmFetchKit.GetById('account', accountId, columns).then(function(account) {
console.log(account.getValue('name'));
});
GetByIdSync
var accountid = '06887701-2642-4a53-99ba-c24ce1a5688b',
columns = ['name', 'donotfax', 'donotemail', 'createdon'],
account;
account = CrmFetchKit.GetByIdSync('account', accountId, columns);
console.log(account.getValue('name'));
Fetch
With the Fetch
method is it possible to execute fetch-xml based query.
The method will resolve the promise with an array of BusinessEntity
objects. These type supports the method getValue(<%attributename%>)
.
The following code load all account records with the name foobar
and prints the names to the console.
var fetchxml = [
'<fetch version="1.0">',
' <entity name="account">',
' <attribute name="name" />',
' <attribute name="accountid" />',
' <filter type="and">',
' <condition attribute="name"',
' operator="eq" value="foobar" />',
' </filter>',
' </entity>',
'</fetch>'].join('');
CrmFetchKit.Fetch(fetchxml).then(function(entities){
for(var i = 0, max = entities.length; i < max; i++) {
console.log(entities[0].getValue('name'))
}
});
FetchSync
var fetchxml = [
'<fetch version="1.0">',
' <entity name="account">',
' <attribute name="name" />',
' <attribute name="accountid" />',
' <filter type="and">',
' <condition attribute="name"',
' operator="eq" value="foobar" />',
' </filter>',
' </entity>',
'</fetch>'].join('');
var entities = CrmFetchKit.FetchSync(fetchxml);
for(var i = 0, max = entities.length; i < max; i++) {
console.log(entities[0].getValue('name'))
}
FetchMore
In a situation where the developer needs more control over the loaded data, the FetchMore
method should be used. The method will resolve the promise with an object that supports the following properties:
totalRecordCount
(number)moreRecords
(boolean)pagingCookie
(string)entityName
(string)entities
(array obBusinessEntity
objects)
var fetchxml = [
'<fetch version="1.0"',
' returntotalrecordcount="true" ',
' count="10">',
' <entity name="contact">',
' <attribute name="lastname" />',
' <attribute name="contactid" />',
' <filter type="and">',
' <condition attribute="lastname" ',
' operator="like" value="foobar" />',
' </filter>',
' </entity>',
'</fetch>'].join('');
CrmFetchKit.FetchMore(fetchxml).then(function(response){
console.log(response.totalRecordCount);
console.log(response.moreRecords);
console.log(response.entityName);
console.log(response.pagingCookie);
for(var i = 0, max = response.entities; i < max; i++){
console.log(response.entities[i].getValue('lastname'));
}
});
FetchMoreSync
var fetchxml = [
'<fetch version="1.0"',
' returntotalrecordcount="true" ',
' count="10">',
' <entity name="contact">',
' <attribute name="lastname" />',
' <attribute name="contactid" />',
' <filter type="and">',
' <condition attribute="lastname" ',
' operator="like" value="foobar" />',
' </filter>',
' </entity>',
'</fetch>'].join('');
var CrmFetchKit.FetchMoreSync(fetchxml);
console.log(response.totalRecordCount);
console.log(response.moreRecords);
console.log(response.entityName);
console.log(response.pagingCookie);
for(var i = 0, max = response.entities; i < max; i++){
console.log(response.entities[i].getValue('lastname'));
}
FetchAll
To address the 5.000 records query limit of Dynamics CRM (a single request return at a maximum 5.000 records) provides the CrmFetchKit with the FetchAll
method an option to load all records retunred by an query.
Note: This method supports only the asynchronous execution.
// query loads all contact records in the system
var fetchxml = [
'<fetch version="1.0">',
' <entity name="contact">',
' <attribute name="lastname" />',
' <attribute name="contactid" />',
' </entity>',
'</fetch>'].join('');
CrmFetchKit.FetchAll(fetchxml).then(function(entities){
for(var i = 0, max = entities.length; i < max; i++) {
console.log(entities[i].getValue('lastname'));
}
});
Internally uses FetchAll
the FetchMore
method and the provided pagingCookie
to load the pages until all records are loaded.
FetchByPage
This method allows the load of records per page-number.
// load records from the first page
CrmFetchKit.FetchByPage(fetchxml, 1).then(function(responsePage1) {
// load records form the second page
return CrmFetchKit.FetchByPage(fetchxml, 2, responsePage1.pagingCookie)
.then(function(responsePage2){
//...
});
})
Assign
The Assign
method allows the modification of the owner of an CRM record.
var contactid = '06569fb8-88d0-4588-bdb8-c20c19e29205',
// the team is the new owner of the concact record
teamid = '4797f323-76ac-4cf7-8342-b7c1bafd5154';
CrmFetchKit.Assign(contactid, 'contact', teamid, 'team').then(function(){
//..
});
AssignSync
var contactid = '06569fb8-88d0-4588-bdb8-c20c19e29205',
// the team is the new owner of the concact record
teamid = '4797f323-76ac-4cf7-8342-b7c1bafd5154';
CrmFetchKit.AssignSync(contactid, 'contact', teamid, 'team');
Note: The parameter for this method have change form the 1.x version of the CrmFetchKit. The old version supported only the assignment of SystemUsers
where the current version supports Teams
and SystemUsers
.
Promise Member
Since version 3.3.0 support exposes the library the object Promise
. This is only the reference
to the internally used bluebird library.
CrmFetchKit.Promise
.all([CrmFetchKit.Fetch(xml1), CrmFetchKit.Fetch(xml2)])
.then(function () {
console.log("all in");
});
Support for Joins
FetchXml support the joining via the "link-entity" tag. In case the query yields attributes of the linked entity, an alias must be provided to access these attributes with the getValue()
method of the business-entity object.
The following query uses the alias bu
to identify the attributes of the joined entity businessunit
:
// the query loads all account records that belong to the root business unit
var fetchxml = [
'<fetch version="1.0">',
' <entity name="account">',
' <attribute name="name" />',
' <link-entity name="businessunit" from="businessunitid"',
' to="owningbusinessunit" link-type="inner" alias="bu">',
' <attribute name="name" />',
' <filter>',
' <condition attribute="parentbusinessunitid" operator="null" />',
' </filter>',
' </link-entity>',
' </entity>',
'</fetch>'].join( '' );
In order to access the attributes of the buinsess-unit record, the notation <%ailas%>.<%attributename%>
must be used:
CrmFetchKit.Fetch(fetchxml).then(function(entities){
var first = entities[0];
console.log('Name of the business-unit: ' + first.getValue('bu.name'));
console.log('Name of the account: '+ first.getValue('name'));
});
Support for asynchronous and synchronous execution
The methods Fetch
, FetchMore
and Assign
support the options parameter opt_async
(default is set to true
). Due to the default value, will the library execute the operation in asynchronous mode when the very last parameter is omitted.
CrmFetchKit.Fetch(query);
To executed the operation in synchronous mode, the last parameter must be set to false
when invoking the function
CrmFetchKit.Fetch(query, false);
The method FetchAll
supports only the asynchronous execution.
Installation
The GitHub folder build
hosts two file: CrmFetchKit.bundle.js
, CrmFetchKit.min.js
, just download one of these files and deploy the script as web-resource to your CRM server.
Note: The library uses bluebird for the promise features. The build step (gulp) generates the file CrmFetchKit.bundle.js
and this file already contains bluebird. So it is not necessary to deploy bluebird as additional web-resource to Dynamics CRM.
Bower.io
This module could be installed via bower:
bower install crmfetchkit
npm package
This module could be installed via npm, the first version supporting npm is 3.2.0:
npm install crmfetchkit
Build
To build the library from source-code the following components are required:
- Node.js
- bower.io
Open the command line, navigate to the root folder and enter the following command:
npm install
This will install all the needed node.js packages for the task-runner and the build process.
Next we need to install the client dependencies. Enter the following command:
bower install
Testing
Unit Test
A very simple unit-testing is implemented (based on karma. The test only verifies some basis conditions.
Run the following command to execute the unit-tests:
gulp test
Integration-tests
Part of build task is the file "SpecRunner.html" generated. This HTML file contains all dependencies (e.g. mocha.js
, chai.js
, CrmFetchKit.bundle.js
...) so the you need only to deploy this single HTML file as web-resource your environment.
Versions
Version 3.x
This version replaced jQuery dependency with bluebird. Due to the use of bluebird instead of jQuery, some method are no longer available by the returned promise:
always
instead usefinally
fail
instead usecatch
Breaking Changes
The optional async
for Fetch
, FetchMore
and Assign
is no longer supported. All methods are now async. That means that CrmFetchKit.Fetch(xml, false)
will not perform a synchronous operation. To execute a sync operation use one of the *Sync
methods (e.g. FetchSync
, FetchMoreSync
).
Furthermore supports the library now the methods GetById
and GetByIdSync
.
Note: Unfortunately depends CrmRestKit.js
(use for the integration-tests) still jQuery. Therefor is it not possible to remove the jQuery dependency for now.
Internally uses CrmFetchKit now browserify for the dependency management.
Version 2.x
The version 2.x of the library uses Mocha.js as testing framework (instead of QUnit) and Gulp.js for the task automation (linting, build, minify, etc.)
Breaking Changes
- Before this version the
getValue
method returns anstring
foroption-sets
attributes. With the 2.x version, the method return a value of typenumber
.- See integration test
should retrieve the optionset-value as "number"
- See integration test
- The
Assign
method accepts now five attributes (id
,entityname
,assigneeId
,assigneeEntityName
,opt_async
).
Versions 1.x
Previous versions (1.x) of this library are available on CodePlex (http://crmfetchkit.codeplex.com/)