Programming with the JavaScript Object Model

The core elements from architecture through CRUD

David Mann

by David Mann on 6/4/2014

Share this:
Print

Article Details

Date Revised:
6/4/2014

Applies to:
Architecture, Batch, CRUD, Exception Handling, javascript, JSOM, JSON, security


The JavaScript Object Model is expanded in SharePoint 2013 from what was available in 2010. It has also grown significantly in importance with the introduction of the app model, as well as the evolution of SharePoint sites and applications. This chapter covers core elements of the JavaScript Object Model—from architecture through CRUD operations—that developers must be familiar with.

The JavaScript Object Model (JSOM), which was introduced in SharePoint 2010, is not new in SharePoint 2013. It is, however, more important now because the new app model in SharePoint 2013 makes any means of off-server programming critically important. This chapter will introduce JSOM, walk through some important architectural detail, examine CRUD operations, and review security programming.

To understand the code examples in this article, you need to be familiar with some important architectural aspects of JSOM. With that foundation, you can examine some examples of CRUD operations, starting with simple reads before proceeding to creating, updating and deleting. Finally, you’ll find a discussion on interacting with SharePoint security.

JSOM was introduced in SharePoint 2010 as one third of the new Client Side Object Model (CSOM).  Since that time, the CSOM moniker has been associated more with the .NET and Silverlight managed code portions of the client side object model. JSOM has been associated with the JavaScript portion--though that strict separation is not entirely accurate, especially within the official documentation, which rarely if ever uses JSOM.

Naming confusion aside, JSOM code is simply a JavaScript library that provides access to SharePoint from client browsers.  JSOM is downloaded from the server to the browser on demand, just like any other JavaScript library.

You need to know the following two important things about JSOM before getting started with it:

Authentication: JSOM provides no ability to impersonate or login.  All code executes within the user context established by the browser. So your JSOM code will run as whomever you’re logged in to SharePoint as in the browser.  There’s nothing you can do about that. 

Context: JSOM code requires a SharePoint context.  It must be run on a page that has been downloaded from a SharePoint site, so it is not a candidate for running on non-SharePoint sites or apps, except SharePoint-hosted apps. 

This chapter will focus on the capabilities of JSOM regardless of whether it originated in a farm solution, a sandbox solution or an app.  The focus here is learning how to work with JSOM in preparation for layering in the situation-specific elements later.

An important aspect of JSOM is that by default, it is limited to accessing SharePoint within the current site collection – that is, within whichever site collection owns the page that delivers the JavaScript.  There are ways around this limitation which we’ll cover later.

Let’s start with a focus on plain JSOM with nothing fancy. This means that even though the user running the JavaScript code may have rights to multiple site collections, may even be a site collection administrator on multiple site collections, the JSOM code running in that user’s name can access only resources within its originating site collection.  It cannot access a different site collection.  This is a limitation of JSOM that we just need to deal with for now.  Within the originating site collection, the JSOM code can access any constructs or content the current user has access to.

Architecture

From an architectural point of view, JSOM is organized into libraries, just like any other JavaScript API.  You’ll need three libraries in SharePoint 2013, all of which are made available via the out-of-the-box Master Pages.  If you’re creating your own Master Page, make sure you load:

MicrosoftAjax.js – typically loaded via ScriptResource.axd

SP.Runtime.js – loaded from the LAYOUTS folder

SP.JS – also loaded from the LAYOUTS folder

These libraries, together, allow us to work with JSOM and interact with the SharePoint server and the client UI.  We don’t typically inspect or work directly inside these files, they are just prerequisites for our JSOM code.  In fact, as with any other default, out-of-the-box SharePoint file, we don’t want to crack these open and edit them directly.

In the next chapter, we’re going to talk about interacting with SharePoint via the REST API, which is more like regular JavaScript programming.  For now, though, we’re focusing on JSOM, which gives us a significant benefit over REST: JSOM abstracts away most of the plumbing and behind-the-scenes messiness of REST and gives us nice, simple objects to work with. These objects will be immediately familiar to anyone who has done server-side SharePoint development. (Purists and REST enthusiasts say this is a problem with JSOM and makes it non-standard, but I prefer to think of it as just another tool in our toolkit.) 

The familiar objects JSOM provides include things like Web, List, ListItem, things that are similar to their server-side equivalents – SPWeb, SPList and SPListItem, for example.  We work with the members – properties and methods – of these objects and can mostly forget about the JavaScript messiness underneath – arrays, objects, object literals, and the like. 

There is some messiness we need to deal with, though. It isn’t all entirely abstracted away from us.  But let’s get through a little bit more architecture first.

Asynchronous programming

One of the items that IS abstracted away is the plumbing aspect of actually calling back into SharePoint.  We don’t need to worry about packaging the data, sending it up the wire, waiting for a response and so on.  All of that is handled for us, which a lot of developers find nice.  The call back to SharePoint goes to a REST service named client.svc and is done asynchronously – meaning that the call is made but we don’t wait for a response.  Instead, once the call is sent up, our code continues running, and when the response comes back from the server, one of two callback functions we registered will be called, depending on whether the call succeeded or failed on the server.  The important point here is the asynchronous nature of JSOM.

Context

The next core architectural concept to tackle is Client Context.  Server-side code often revolves around the idea of context and specifically the SPContext object; similarly client-side code revolves around the Client Context – perhaps even more so than on the server-side Context. 

Client Context in JSOM is our connection back to SharePoint; it is the center of our world from which all things originate. Establishing the Client Context is the starting point of all our code.

To get a client context in JSOM, you have two options: new or get_current.  The former, new, is going to create a new context for the web whose relative URL we specify as a parameter – or for the current web if we don’t supply a parameter.  The latter, get_current, returns the current context for the page, creating it first if it does not exist already.  Several examples of getting a context object, along with explanatory comments, are shown in SNIPPET 1.

snippet1

sidebar

Batching

The next architectural element to touch upon is the one that usually gives people headaches.  The JavaScript code we write and that gets run inside the user’s browser does not execute sequentially.  It gets READ sequentially, but some of it is queued for later execution, while some of it executes right away.  This is the part that causes the headache – keeping straight which code executes when.

In FIGURE 1 we see a representation of some JavaScript code – a snippet from a small function called simply doWork.  Without going into details, because we haven’t introduced this yet, it is easy to discern what is happening here – we’re simply retrieving a list called MyListName. (As this snippet illustrates, JSOM is generally easy to read and understand, which is one of the benefits for beginners.)

batch

The first line in this function establishes our context.  Don’t worry about not understanding the details of the code at this point. For now, I want you just to look at the lines of code as work that needs to happen. 

The JavaScript parser in the user’s browser reads this first line and executes it.  But executing a line of JSOM doesn’t typically mean that the work happens.  After this line is executed, we don’t yet actually have a context to work with.  Instead, what happens is that this line of code is added to a batch; it is queued up.  Same with the

next line, which gets the collection of lists in our current web.  Same, too, with the next line, which gets the list we are looking for.  It is only when the browser reads and executes final line, shown in FIGURE 1 that things happen and get interesting.  The function executeQueryAsync does not get added to the batch, but does cause the batch to get sent to the server for processing. 

SNIPPET 2 shows a full example of a JSOM method, including the executeQueryAsync call, with comments to help you understand what is happening.

snippet2

As the batch hits the wire to go up to the server, any code following the executeQueryAsynch call begins processing immediately. It is an asynchronous call; it does not wait for the batch to return.   As part of the executeQueryAsynch call, we register two callback functions: one if the batch processes successfully on the server, and one if it encounters an unhandled error. 

While all this is happening on the client, the server receives the batch (on the client.svc REST endpoint), rips open the XML payload, and begins processing it.  All of the work is done by the regular server-side object model interacting with the SharePoint databases as required.

If the server processes the batch with no unhandled exceptions, the JSON results object is sent back to the client with an indication that everything ran OK, and so the success callback is called.  If, however, an unhandled exception occurred while the server was processing the batch, the results go back to the client (again as JSON) and call the failure callback.

That is, in a nutshell, how the JSOM processes a batch of commands.  While we don’t deal with many of the plumbing aspects of adding commands to the batch and handling the results to get things to the right callback, it is nonetheless important to understand this process.  Arguably, this is the most difficult part of JSOM, which is unfortunate as it impacts everything we do in JSOM.

One point to reiterate about the batching process is that it applies only to JSOM code – specifically things that make use of JSOM client objects.  Regular JavaScript is not impacted by the batching.  JSOM object code is added to the batch, but non-JSOM code is executed immediately.  Even when this regular JavaScript code is intermingled with JSOM object code, the batching does not apply to non-JSOM code.  This can lead to some confusion as you’re getting started with JSOM programming as it seems your code is sometimes not executing in order.  You’ll get a better feel for the implications of this and how to deal with it as you get more comfortable with JSOM and asynchronous programming in general.

To close out this discussion of the batching process, I’ll wrap up with the reason the batching model is used: It’s all about performance.  Sending commands over the wire is the slowest part of client-server interaction.  If our client-side code hit the wire with every command issued and had a corresponding response from the server, performance would be horrible.  The amount of overhead involved would bring our application to a crawl.  By reducing the chattiness of our application, and therefore the number of times traffic hits the wire, we can improve performance.

Exception Handling

Handling exception conditions is an important part of any professional development effort.  Unfortunately, it is one that is far too often ignored in JavaScript.  When all JavaScript was doing was delivering eye candy, this was perhaps not such a big deal.  However, as JavaScript is becoming more involved in manipulating data and things that have real business impact, this is a problem.  JavaScript natively supports error handling through the same try/catch/finally paradigm we know and love.  Unfortunately, this is all client-side, and when we commit a batch to the server, we don’t want to be adding multiple extra roundtrips to our experience if an error happens in the batch. 

The ability to include the try/catch/finally information as part of the batch would be better; essentially saying: Try these things up on the server.  If an error occurs, do these things, then no matter what, do these things.  NOW hit the wire again and come back down to the client and tell me what happened.

Fortunately, that’s exactly what we get in JSOM.

SNIPPET 3 shows a full example of exception handling in JSOM.  We start by getting our client context, as we talked about previously.   Then, on line 3, we create an instance of an ExceptionHandlingScope object and call its StartScope method (line 4) to indicate that we’re beginning an exception handing block.    Next we need to indicate that we’re beginning our try block.  We do that by calling the startTry method on our scope (line 5).  Now we can do whatever code we want that could cause an error.  In this case, I’m trying to get a list that doesn’t exist (line 8).  To signify the end of the try block and clean things up, we dispose of our try object on line 9.

Next we need to specify the steps we want to happen if an error happens in the try.  We do this in a similar manner by instantiating and disposing of a catch block (line 11 to start the block, line 13 to close the catch block).  Inside the block, we indicate the steps to take on the server if an error happened anywhere in the try block. 

One thing is important to keep straight inside your exception handling, especially in the catch and later the finally sections: This is part of our batch; it executes on the server once the batch is committed.  If you intermingle regular non-JSOM JavaScript inside these blocks, it will execute immediately, on the client, regardless of whether an error actually happened. This is likely not what you want. 

That’s an important facet of this that bears repeating: Just because you put some regular JavaScript inside, say, the catch scope, doesn’t mean that it only gets executed if an error occurs and the catch block is entered.  Remember that exception handling blocks are added to the batch and aren’t executed until they get up to the server. 

Trying to insert regular client-side JavaScript into that will just not work.  Most often I’ve seen this burn people who are trying to log something or notify the user that an error happened. 

The finally part of our exception handling happens exactly the same as the try and the catch. Start the scope (line 15), indicate what you want to have happen up on the server regardless of whether an error occurs (line 16), and then dispose of the finally block (line 17).

The last step is to simply clean up the exception scope (line 19) and then call executeQueryAsync (line 20) to commit the whole batch – try/catch/finally and all – up to the server to be processed.

snippet3

That’s how we do exception handling in JSOM to maintain the integrity of our batch and keep our application from being excessively chatty, even if something goes wrong. 

Even if we properly set up our server-side error handling as shown in SNIPPET 3, it may still be necessary to be able to detect that the error happened on the server when things get back down to the client.  Fortunately, it’s both possible and easy to do so.  Remember, though, that the error has already happened and been dealt with on the server as part of our batch.  Most of the time, this is sort of informational only.  You may or may not want to tell the user about the error.

The first important thing to know is that if an error occurs and is handled as part of our batch, it is not considered a failed batch when things get back down to the client.  The onSuccess handler is still called.  The onFail callback is only called if an unhandled exception occurs on the server within our batch.

SNIPPET 4 shows an example of how to detect from the client that an error happened and was handled on the server as part of our batch.  Inside the onSuccess callback, we can check the ExceptionHandlingScope object we set up back in SNIPPET 3 to see whether an error happened and was handled.  Specifically we use the get_hasException function to check the HasException property of the scope.

snippet4

If that returns true, we know an error happened and was handled on the server.  If it returns false, no error happened.  Remember, we wouldn’t even be in the onSuccess callback if an exception happened on the server and wasn’t handled.

Once we know that an error occurred, we can take whatever client-side actions we want to take.  We can get information about the error by checking the ErrorMessage property of the ExceptionHandlingScope object via the get_errorMessage function, as shown in SNIPPET 4, line 7.

Reading Data

With a good understanding of the core elements of the JavaScript Object Model, we can now begin to look at using JSOM to interact with SharePoint.  We’ll start with a look at doing simple reads of information.  As with the server OM, this mostly deals with Webs, Lists, ListItems and Files.  Naturally, we can interact with many more objects, but once you get the model down using these basics, the rest is pretty straightforward.

snippet5

SNIPPET 5 shows our first example, which we’ll go through in detail.  Just like some things we’ve seen already, we start with getting our context in line 2.  In this example, we are instantiating a new context object but not supplying a parameter, so we’ll get a connection to the current web.  Once we have that, we can instantiate the objects we’re going to deal with, in this case the web and the lists collection for the web. 

One thing unique to client-side programming in SharePoint is the need to fill up our objects so that their properties get populated with values.  This is distinctly different from the server-side object model in which merely instantiating or retrieving an object causes its properties to be populated. 

We populate our objects by passing the object we wish to fill up into the Load method of the client context object.   You can see an example of this in the commented out line 6 of SNIPPET 5.  The line is commented out because of an important detail about loading up objects that we’ll discuss next: If this line were not commented out and so executed, most of the properties on that object would be filled with their values when the batch is committed. That likely isn’t what we want. 

Traversing the wire is the most expensive part of our operations from a time and performance perspective.  To help reduce the impact of this factor, we want to avoid retrieving any data that we do not need.  This makes perfect sense. If we’re not going to use a piece of data: Why bother retrieving it and pulling it down?  Applied to objects and their properties, this means that we only want to populate the properties we’re going to work with. 

This is the important detail about the Load statement.  We reduce the amount of data retrieved by specifying which properties we want filled up as part of the Load statement.  In line 4 of SNIPPET 5, we’re loading our Web object, but just the Title and ServerRelativeUrl properties because that’s all we’re going to work with.  Notice the syntax on line 4. We specify the field names as a comma-delimited series of individual strings, each enclosed in either single or double quotes. 

This syntax is used when we are filling up a single object.  If you look at the code in line 7, you’ll see a slightly different syntax: the use of the word Include and then the names of the properties we want filled up, in this case Title and Id.  This syntax is used only for loading up a collection of other objects (here, lists), but other object collections, as well.  This syntax specifies which properties of the items in the collection will be populated. 

Finally, we need to commit our batch by calling executeQueryAsync on line 8.  This sends our commands up the wire to the SharePoint server.  If no errors happen while the commands are executing on the server, the response will come back to the OnSucceed callback we registered in the executeQueryAsync call earlier.

In our success callback, we can begin to work with the objects we instantiated and the properties we asked to have filled up with their values.  In lines 12-14 of SNIPPET 5, you can see that I’m accessing the ServerRelativeUrl and Title properties of my Web object, as well as the Count property of the Lists collection.

So we need to fill up the properties of our objects before we work with them, and we do this with the Load function, as we’ve seen.  But what happens if we don’t?  If we try to work with a property that has not been populated with a value, we will get a PropertyOrFieldNotInitializedException. 

Get used to seeing this.  Even if you’ve worked with JSOM a lot, you will see this error.  Fortunately, the fix is easy. You just need to make sure you are loading every property you try to work with. 

Unfortunately there’s more to it than just filling up properties in the simple manner we’ve seen, and this it makes things a little more complicated in some cases.  When we fill up an object via the Load function, it’s reasonable to expect that if we don’t limit the properties that are filled up, they will ALL be populated.  But things don’t work that way.  Some properties are not filled up when you just call Load, unless you specify which properties you want populated.  In general, when you do not specify which properties to load, only the scalar properties are filled up. 

Scalar properties are any properties that return values of one of these data types (or an array of one of these data types):

  • Bool
  • Byte
  • Char
  • DateTime
  • Number
  • Guid
  • String

Properties that return other types of values, specifically collections and JSOM client objects, must be explicitly loaded.  This is why, in SNIPPET 5, we had to explicitly call Load on line 7 to populate the lists collection, even though it is a property of the web object that we already loaded.  True, in this snippet, we limited the properties of the web object that were loaded, But even if we had simply called currCtx.Load(myWeb) to load all properties of the web object, the lists collection would not be populated because it is a collection of JSOM client objects, not a scalar property.

Because every good rule needs an exception, some scalar properties are not filled up, even if we just accept the filling up of only the default properties by not specifying any properties to load.  TABLE 1 shows which of the scalar properties for various objects are not filled up by default and must be explicitly requested if you need them.

You really shouldn’t look at this as a problem because you really ought to be specifying exactly which properties you are going to work with later--no more, no less. This would mean that all the properties you need – regardless of their type – are properly populated when you need them.  If you take that approach, then this problem vanishes.

You need to understand the details of loading objects, though, because you need to remember that collection and non-scalar properties and even certain scalar properties must be explicitly requested.

table1a

That wraps up the general information you need to know about reading data from SharePoint.

CAML queries

So far, we’ve seen reading data from SharePoint, but we’ve stopped basically at the web or list level.  A far more common scenario is to continue further down and start working with list items.  One of the most common approaches for getting to one or more list items is the same approach we’d use in server-side code – a straightforward Collaborative Application Markup Language (CAML) Query.

In SNIPPET 6, we start by getting our context and the list that contains the items we want to work with – here an Announcements list simply called News.  In line 5, we create a new object, one we haven’t seen before but that ought to be familiar to you - SP.CamlQuery.  Like its server-side cousin, this object allows us to specify the CAML query that expresses the criteria used to define the items we want to retrieve; in this case, items that have a Title value of xyz.  The actual XML that makes up the CAML query is on lines 6-11 in SNIPPET 6.  This is a pretty simple CAML query, which as I said, filters on the Title column.  If you look at this CAML statement, it should look familiar to anyone who has worked with its server-side equivalent.  The syntax is slightly different, but not disconcertingly so – it’s really just the addition of the <View> and <Query> elements. 

Next we pass the CamlQuery object into the getItems method of the targetList object and store the results in the listItems variable (line 12).  On line 13 we load the listItems object (filling up only the Title property) and on line 14 commit our batch to the server.

When the batch returns from the server, hopefully to our success method, we can start to work with the items in the collection of results.  In this approach, we do that by getting an enumerator on line 18 and iterating through the collection one item at a time in the while loop beginning on line 19.  You can see how we access the individual fields on a listItem by using the get_item method and passing in the InternalName of the field whose value we wish to retrieve.  This will work for any field type, though for some like Hyperlink fields, you need to go a little further to get meaningful values.

snippet6

In SNIPPET 6, we filled up the listItems variable with the results of the CAML query and it held a collection of listItem objects that we could loop through via the enumerator.  This is called an in-place load.  Another approach, which honestly gives us the same results but may be more familiar to some developers, is to do what’s called a queryable load, as seen in SNIPPET 7.  In this approach, the call to fill up the listItems object uses the loadQuery function (line 11) instead of the Load function.  The results of that call are stored in a separate variable – results – on line 11.

snippet7

After committing our batch on line 12 and returning back into the onQueryableLoadSucceed, what we get back is not a listItemCollection object as we did before, but rather an IEnumerable collection of listItem objects. What that means is that in the success callback, we can loop through the results a little more easily – using a simple for loop instead of getting the enumerator manually and looping through the collection with it.  Again, not a huge difference, but one that may be more comfortable for some developers.  There are no performance benefits to one approach over the other. 

The only significant, noticeable difference between the two methods is related to object identity.  In the case of an in-place load, object identity is maintained by the client context object.   What this means is that if you query the server via an in-place load to retrieve an object, update some properties of that object, and then re query the server to re-load the same object, the properties that you modified on the client are maintained at their updated values.  Context understands that these are the same objects you retrieved and worked with before and so it merges the two instances into a single identity.

This is not the case with queryable loads.  In a queryable load, object identity is not maintained so the collection of objects retrieved from the server will have only the values the server has, not anything that may have been previously edited on the client but not yet committed to the server.

From a real-world point of view, what this boils down to is a general guideline: Use an in-place load for objects you will be updating and a queryable load for objects that you will just be reading.  That’s just a general guideline and certainly not one cast in stone.  If you are more familiar with one or the other of the approaches, there is likely not a meaningful reason to not just use that one approach all the time.

Creating

The next operation we need to take a look at is the creation of SharePoint constructs – lists, listitems, etc.  This operation is different from its server-side equivalent in that anything creatable via JSOM has a corresponding CreationInformation object.  Creating something entails instantiating a CreationInformation object, filling its properties, adding it to the parent collection, and then committing the batch to the server.  The full list of creatable objects can be determined from the available CreationInformation objects:

  • ContentTypeCreationInformation
  • FieldLinkCreationInformation
  • GroupCreationInformation
  • ListCreationInformation
  • ListItemCreationInformation
  • NavigationNodeCreationInformation
  • RoleDefinitionCreationInformation
  • UserCreationInformation
  • ViewCreationInformation
  • WebCreationInformation

SNIPPET 8 shows an example of creating a List.  The rest of the creatable objects are dealt with similarly.

snippet8



In SNIPPET 8, you can see the use of the ListCreationInformtion object. We create an instance of the object and set a few of its properties – specifically the templateType, in this case an Announcements list, the title, and quickLaunchOption.  We then pass the ListCreationInformation

object in to the add function on the lists collection of the current web and commit our batch.  That’s all it takes to create a list using JSOM.

Updating

Before we can update an item, any item, we need to retrieve it.  Typically we need to retrieve the target item’s parent container first, but in a few cases we get the item directly.  Depending on what type of item we’re trying to update, we’ll get a different container:

  • For webs, we get the Webs property of the parent site collection or the web property of context
  • For Lists, we get the Lists property of the parent web
  • For list items, we get either the items collection of the parent List, use a CAML query like we saw in SNIPPET 6 and SNIPPET 7, or use a function of the parent List object to get the item directly, which is what we’ll see in SNIPPET 9.
  • And so on – other items are going to be similar

Updating list items

In SNIPPET 9, we have code that goes through and gets the Announcements list.  This should look familiar as we’ve seen similar code several times already.  Next we retrieve the item we wish to work with.  On LINE 6 we’re using the getItemById function of the list object and passing in the ItemId.

Once we have the item, we use the set_item function to give a field a new value, as shown in SNIPPET 9, line 7.  As you can see, we pass in the name of the field we want to update (for line 7, “Title”) and the new value for the field (“updated from JavaScript”).  Finally, we simply call the update method and commit our batch to the server.

That works fine for simple value field types like text and numbers.  For complex field types, we need to use the specific field value object for the field type.  Complex field types include:

  • URL
  • User
  • Lookup
  • GeoLocation

So, for example, setting a URL field - which consists of two parts, the hyperlink value and the description, or text of the hyperlink - requires the use of a FieldUrlValue object.

snippet9

An example of this object is shown in lines 8-11 of SNIPPET 9.  Usage of the other field value objects is similar to the FieldUrlValue object:

  1. Create the field value object (SNIPPET 9, line 8)
  2. Set its properties (SNIPPET 9, lines 9 & 10)
  3. Use the set_item function to update the item (SNIPPET 9, line 11)

Updating other objects

The approach we’ve covered so far works for List Items and also folders, which are essentially specialized list items.  But things are a little different when we’re dealing with other objects such as Lists or Webs.  In those cases, setting a new value for a property is simply a matter of calling the JavaScript property setter, which has the syntax set underscore and then the name of the property, all in lowercase.  So, for example, setting a new value for the Title of a list is simply a matter of calling the set_title function and passing in the new value.  SNIPPET 10 shows a few examples of updating properties of other types of objects in SharePoint.

As before, after setting the properties, we simply need to update and then commit the batch as seen on lines 12 and 14 of SNIPPET 9.

snippet9

Form digest

One final thing to know whenever you are trying to change something in SharePoint via JSOM - you must have a FormDigest control on your page.  It can be directly on the ASPX page, but is more commonly included via the MasterPage.  FormDigest is a cryptographic protection against script replay attacks.  For regular JSOM work, just make sure it’s available – again, typically from the Master Page.  An example of a FormDigest tag is shown in SNIPPET 11.

snippet11

Deleting

Deleting objects is pretty straightforward: Simply retrieve the object, and then call its deleteObject method.  SNIPPET 12 shows several examples of deleting various objects.

snippet12

Security programming

One of the nice things about JSOM in SharePoint 2013 is the ability to interact with the security infrastructure of SharePoint.  Even if you never use this capability to manage security – setting permissions, managing users and groups, etc. – the ability to check security asynchronously and present or update the UI accordingly is a huge advantage.

Looking in SNIPPET 13 at the ability to check security, we see our standard code for getting context, and in this case, getting our web object.  Next we need to load up the properties on our web object (line 4).  Following best practices, and also because the effectiveBasePermissions property isn’t filled by default (see TABLE 1 earlier in this chapter), we specify that we only want the permission information.  Then, as always, we post our batch back to the server.

In our success callback, we specify the permissions we want to check for (Edit List Items or Full Permissions), storing them in a variable, perms.  Notice that we’re using the SP.PermissionKind enumeration in line 8 to specify the rights we want to check.

snippet13

Then we use the get_effectiveBasePermissions function on our web object, which returns an SP.BasePermissions object that includes a has function.  We use the has function to check whether the current user has the permissions we specify in the parameter.  We can now simply react according to whether the user has the permissions we’ve specified.  In a real application, we would do something besides popping up an alert box, such as hiding or showing UI elements depending on whether the user has the permissions for which we checked.

In addition to Web, the List and ListItem objects also have a get_effectiveBasePermissions function to allow us to check permissions at those levels.  While Folder is a securable object in SharePoint, there is no direct way to work with Folder-level permissions in JSOM.  Similar to the server-side object model, the way to do this is to get the folder object as a ListItem – using one of the methods we saw earlier for retrieving List Items – either a CAML query or getting it by ID.  Once you have the List Item that represents the folder, you can work with the permissions that way.

I used a couple of values from the SP.PermissionKind enumeration in SNIPPET 13.  I have not found a way to get the values for this enumeration to show up in Intellisense; as near as I can tell, it is just not registered properly to do so.  To help you understand the available rights, I’ve duplicated the values from the enumeration in TABLE 3.  The rights themselves are the same things we have server-side.  The main thing to notice is that, similar to many other things in JavaScript, the first letter is lower case, and JavaScript is case sensitive so you need to make sure you get that right.

table3

SNIPPETS 14 through 17 show sample code for some common security programming operations:

  • Getting SharePoint groups
  • Adding a user to a SharePoint group
  • Removing a user from a SharePoint group
  • Creating a new permission level, or role

The code is commented and pretty straightforward, so I won’t walk you through each snippet.

14

1617a17b

Security in apps

Security programming, and in fact security in general, is very different in apps when compared to regular SharePoint sites.  The app security model is focused more on app and user-specific permissions as opposed to groups.  In an App Web, it is possible to add user permissions directly or add new group permissions.  However, it is not possible to create or delete groups, or add users to an existing group, which severely limits the possibilities for managing security in an App.  I hope that this is a scenario we see improving as the App Model matures.

To help clarify what works inside an App, TABLE 4 breaks out some of the common security programming scenarios and shows which work inside the App Web and which do not.

Conclusion

The JavaScript Object Model is not new in SharePoint 2013, having been introduced first in SharePoint 2010.  It is, however, more important now than it was in 2010.  The introduction of the app model in 2013 makes any means of off-server programming critically important.  In this chapter, we introduced JSOM, walked through some important architectural detail, examined CRUD operations and finished off with a review of security programming.  We certainly didn’t cover every possible use of JSOM, but we’ll use JSOM code in other chapters in this book and the other two books in this series, so you’ll see more and more scenarios as we progress.


Topic: Development

Sign in with

Or register

  • Very good article....fully informative
  • David, I think JSOM in SP2010 only work with one Site Collection
    With SP2013, JSOM can work with multiple Site Collections, but these Sites Collection must be in one Web Application.
  • What about performance using JSOM to retrieve from a list with large number of items?
  • Very Useful article for beginners like me. Thanks Dude.
  • Awesome article, helped me a lot.
    I could not locate, code snippet 10 and table 4, could you please make those available