---
title: "Using the ItemService from JavaScript"
slug: "using-the-itemservice-from-javascript"
abstract: "How to access items in JavaScript via the ItemService API."
---
# Using the ItemService from JavaScript

The `ItemService` is a standalone XHR (XMLHttpRequest) library for creating, fetching, saving, and deleting Sitecore items. It has many built-in utilities and helpers to assist you with data transactions between the front end and the back end. The library is `/sitecore/shell/client/Services/Assets/lib/itemService.js`.

> [!note]
> Many of the examples use functionality from Unit.js. If you want to run the examples literally, you must add a reference to Unit.js in your code.

This topic describes the following:

- [Creating items](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Creatinge_items "Creating items")
- [Fetching items](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Fetching_items "Fetching items")
- [Fetching the children of an item](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Fetching_the_children "Fetching the children of an item")
- [Saving items](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Savinge_items "Saving items")
- [Destroying items](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Destroying_items "Destroying items")
- [Searching for items](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Searching_for_items "Searching for items")
- [Creating a dirty item](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Creatinge_a_dirty "Creating a dirty item")
- [Checking if an item is dirty](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Checking_if_an "Checking if an item is dirty")
- [Retrieving an item as raw JSON](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Retrievinge_an_item "Retrieving an item as raw JSON")
- [Tracking items](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Trackable_items "Tracking items")
- [Saving items automatically](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Savinge_items_automatically "Saving items automatically")
- [The hasChanged() method](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_N1525857210269)
- [The revertChanges() method](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_N1525857245746)
- [The Query object](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__The_Query_object "The Query object")
- [Handling promises](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Handlingow_promises_are "Handling promises")
- [Working with middleware](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Working_with_middleware "Working with middleware")
- [Working with event emitters](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__Working_with_event "Working with event emitters")
- [ItemService and validation](https://doc.sitecore.com/xp/en/developers/105/sitecore-experience-manager/using-the-itemservice-from-javascript.html#UUID-153fed3d-2063-90f2-5704-8483b336d2f6_id__ItemService_and_validation "ItemService and validation")

<details>
<summary><h2>Creating items</h2></summary>

You create an item by passing an object and the path in the Sitecore tree where you want the server to create the item, and then calling the `execute` method:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
var aNewGuy = {
  name: "David",
  isActive: true,
  gender: "male"
};
peopleService.create( aNewGuy ).path( "/sitecore/content/home" ).execute().then( function ( david ) {
  david.should.be.an.instanceOf( ItemService.Item );
  david.name.should.eql( "David" );
  david.isActive.should.eql( true );
  david.gender.should.eql( "male" );
  done();
} ).fail( done );

```

You create a dirty item by not calling the execute method:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.create().then( function () {
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>Fetching items</h2></summary>

You fetch an item by ItemID with the `fetchItem()` method:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.should.be.an.instanceOf( ItemService.Item );
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>Fetching the children of an item</h2></summary>

You fetch the children of an item with the `fetchChildren()` method:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.should.be.an.instanceOf( ItemService.Item );
  melton.fetchChildren().execute().then( function ( meltonsChildren ) {
    meltonsChildren.should.be.an.Array.and.have.a.lengthOf( 3 );
    meltonsChildren[ 0 ].should.be.an.instanceOf( ItemService.Item );
    meltonsChildren[ 1 ].should.be.an.instanceOf( ItemService.Item );
    meltonsChildren[ 2 ].should.be.an.instanceOf( ItemService.Item );
    done();
  } ).fail( done );
} ).fail( done );

```

</details>

<details>
<summary><h2>Saving items</h2></summary>

You must either fetch or create an item before you can save it:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.should.be.an.instanceOf( ItemService.Item );
  melton.name = "Melton the Magnificent";
  melton.save().execute().then( function ( savedMelton ) {
    savedMelton.name.should.eql( "Melton the Magnificent" );
    done();
  } ).fail( done );
} ).fail( done );

```

</details>

<details>
<summary><h2>Destroying items</h2></summary>

You must either fetch or create an item before you can destroy it:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.should.be.an.instanceOf( ItemService.Item );
  melton.destroy().execute().then( function () {
    done();
  } ).fail( done );
} ).fail( done );

```

</details>

<details>
<summary><h2>Searching for items</h2></summary>

You can search for an item in two ways: you can use search or you can use query.

### Using search()

You search for an item by passing a search term and then calling the execute method:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.search( "melton" ).execute().then( function ( queryResults ) {
  queryResults.should.have.a.property( "Links" ).and.be.an.Array;
  queryResults.should.have.a.property( "Results" ).and.be.an.Array;
  queryResults.should.have.a.property( "TotalCount" ).and.be.a.Number;
  queryResults.should.have.a.property( "TotalPage" ).and.be.a.Number;
  queryResults.Results[ 0 ].should.be.an.instanceOf( ItemService.Item );
  queryResults.Results[ 0 ].name.should.eql( "Banks Melton" );
  done();
} ).fail( done );

```

### Using query()

You query for an item by passing a query item and then calling the execute method:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.query(( "xxxx-xxxx-xxxx-xxxx" ).execute().then( function ( queryResults ) {
  queryResults.should.have.a.property( "Links" ).and.be.an.Array;
  queryResults.should.have.a.property( "Results" ).and.be.an.Array;
  queryResults.should.have.a.property( "TotalCount" ).and.be.a.Number;
  queryResults.should.have.a.property( "TotalPage" ).and.be.a.Number;
  queryResults.Results[ 0 ].should.be.an.instanceOf( ItemService.Item );
  done();
} ).fail( done );

```

“xxxx-xxxx-xxxx-xxxx” is the Sitecore ID of the query item.

</details>

<details>
<summary><h2>Creating a dirty item</h2></summary>

A dirty item is an item that is only in browser memory and not saved on the server. This can be useful if your application has to wait for user input. Use the following code to create a dirty item:

```csharp
var peopleService = new ItemService( {
    url: "/sitecore/api/ssc/people"
} );
peopleService.create().then( function ( aNewDirtyItem ) {
  /* At this point `aNewDirtyItem` has not been saved */
  aNewDirtyItem.should.be.an.instanceOf( ItemService.Item );
  aNewDirtyItem.name = "Melton";
  /* After modifying the dirty item, now we save it */
  aNewDirtyItem.save().execute().then( function () {
    done();
  } ).fail( done );
} ).fail( done );

```

</details>

<details>
<summary><h2>Checking if an item is dirty</h2></summary>

You can check if an item has not been saved (it is a “dirty item") with the isNew property:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.create().then( function ( guy ) {
  guy.isNew.should.be.true;
  done();
} ).fail( done );

```

When an item comes from the server, isNew is always false:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.create( {
  name: "guy"
} ).execute().then( function ( guy ) {
  guy.isNew.should.be.false;
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>Retrieving an item as raw JSON</h2></summary>

You may need to retrieve the data of an item as raw JSON (without all of the additional methods and properties). Use the following code to retrieve an item as raw JSON:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  var meltonAsJSON = melton.json();
  melton.should.be.an.instanceOf( ItemService.Item );
  meltonAsJSON.should.be.an.instanceOf( Object );
  meltonAsJSON.should.not.be.an.instanceOf( ItemService.Item );
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>Tracking items</h2></summary>

You can add tracking to an item. This makes it possible to add additional functionality:

- The item can be saved automatically when a property changes.
- You can call hasChanged() to see if the item has changed.
- You can call revertChanges() to revert property values.

You set the trackable option to `true` to add tracking to your item:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).option( "trackable", true ).execute().then( function ( melton ) {
  melton.option( "trackable" ).should.be.true;
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>Saving items automatically</h2></summary>

You can specify that Sitecore.Services.Client saves changes to an item automatically. Set trackable to `true` to turn this feature on. You can listen to the save event by using the emitter “on” or “once”:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).option( "trackable", true ).execute().then( function ( melton ) {
  /* Listening to the `save` event `once`. You can also use `on` here to continuously listen to the `save` event. */
  melton.once( "save", function ( error ) {
    done();
  } );
  melton.name = "Melton the Magnificent";
} ).fail( done );

```

</details>

<details>
<summary><h2>The hasChanged() method</h2></summary>

You can specify that the `ItemService` adds the `hasChanged()` method by setting trackable to `true`. You use the hasChanged() method to check if an item has changed:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).option( "trackable", true ).execute().then( function ( melton ) {
  melton.hasChanged().should.be.false;
  melton.name = "Melton the Magnificent";
  melton.hasChanged().should.be.true;
  done();
} ).fail( done );

```

The `hasChanged` method does not return true if a value changes between null, undefined, and ‘’ (the empty string):

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).option( "trackable", true ).execute().then( function ( melton ) {
  melton.hasChanged().should.be.false;
  melton.subscribed = "";
  melton.hasChanged().should.be.false;
  melton.subscribed = null;
  melton.hasChanged().should.be.false;
  melton.subscribed = undefined;
  melton.hasChanged().should.be.false;
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>The revertChanges() method</h2></summary>

You can specify that the `ItemService` add the `revertChanges()` method by setting trackable to `true`. You use the `revertChanges()` method to revert changes to the item:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).option( "trackable", true ).execute().then( function ( melton ) {
  melton.name.should.eql( "Banks Melton" );
  melton.name = "Melton the Magnificent";
  melton.name.should.eql( "Melton the Magnificent" );
  melton.hasChanged().should.be.true;
  melton.revertChanges();
  melton.hasChanged().should.be.false;
  melton.name.should.eql( "Banks Melton" );
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>The Query object</h2></summary>

Each `ItemService` method returns a query object:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.create( {} ).should.be.an.instanceOf( ItemService.Query );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).should.be.an.instanceOf( ItemService.Query );
peopleService.query( "/sitecore" ).should.be.an.instanceOf( ItemService.Query );
peopleService.search( "sitecore" ).should.be.an.instanceOf( ItemService.Query );
The query object has chainable helper methods. These methods add the given value to the query string of the request:
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.create( {} )
  .database( "master" )
  .facet( "a facet" )
  .fields( "ItemName" )
  .includeMetadata( true )
  .includeStandardTemplateFields( true )
  .language( "en" )
  .page( 2 )
  .path( "/sitecore/content/home" )
  .sort( "aItemName" )
  .take( 5 )
  .version( "latest" )
  .should.be.an.instanceOf( ItemService.Query );
You call the execute() method to run the query. The execute() method returns a promise:
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.should.be.an.instanceOf( ItemService.Item );
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>Handling promises</h2></summary>

Almost all asynchronous calls return a promise. Specifically, and prominently, the `execute()` method returns a promise. The `ItemService` uses the q module to handle this.

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
var fetchQuery = peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" );
var fetchQueryPromise = fetchQuery.execute();
fetchQueryPromise.should.have.a.property( "then" );
fetchQueryPromise.should.have.a.property( "fail" );

```

</details>

<details>
<summary><h2>Working with middleware</h2></summary>

The `ItemService` provides middleware functionality, using the sc-useify module:

```csharp
ItemService.use( function ( data, next ) {
  data.timestamp = new Date().getTime();
  next( null, data );
} );

```

When you have integrated middleware, then the next time you receive data from the server, this data will have a timestamp property:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.should.have.a.property( "timestamp" );
  done();
} ).fail( done );

```

You can clear all middleware workers (or clear by key):

```text
ItemService.useify.clear();

```

Because you cleared all middleware, the data will not have a timestamp property the next time you receive it from the server:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.should.have.not.a.property( "timestamp" );
  done();
} ).fail( done );

```

</details>

<details>
<summary><h2>Working with event emitters</h2></summary>

You can extend items with event emitters:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.on( "save", function ( error ) {
    done();
  } );
  melton.age = 40;
  melton.save().execute();
} ).fail( done );

```

</details>

<details>
<summary><h2>ItemService and validation</h2></summary>

The `ItemService` does not provide any client-side validation. The following example changes the ID of the item to an invalid GUID and then triggers a save. The client will allow the save to execute because there is no validation. However, when the server receives the request with invalid data, it will not resolve and the promise will fail:

```csharp
var peopleService = new ItemService( {
  url: "/sitecore/api/ssc/people"
} );
peopleService.fetchItem( "d4119c4f-31e9-4fd0-9fc4-6af1d6e36c8e" ).execute().then( function ( melton ) {
  melton.ItemID = "invalid guid";
  melton.save().execute().then( function ( badMelton ) {
    should( badMelton ).not.exist;
  } ).fail( function ( error ) {
    error.should.be.an.instanceOf( Error );
    done();
  } );
} ).fail( done );

```

</details>