When Using Angular, Be Sure to Convert to JSON Using `angular.toJson`
This is a quick one, but if it has the potential to bite you, you’ll thank me for it later.
I use AngularJS generally these days when I want to write solutions in SharePoint, whether on premises or in SharePoint Online. Yes, that’s the older version of Angular, meaning versions in the 1.x range.
When you’re using any JavaScript to work with SharePoint data, though, you’ll probably end up converting the data from string-based JSON to JavaScript objects and if you want to save them back to SharePoint, you’ll then convert the data from JavaScript objects back to string-based JSON.
There are two primary ways for do the second conversion:
- JSON.stringify – All “modern” browsers support this function and it works great. If you’ve been doing JavaScript development for a while, you’ll know this function very well – so well that you may rarely think about it when you use it.
- angular.toJson – This is AngularJS’s version of the idea, but it’s smart specifically for objects which are under Angular’s control. In many cases, Angular augments objects with its own properties to keep track of things going on in the page. For example, $$hashkey helps Angular keep track of what objects have changed since a digest cycle.
Depending on how you manage the objects which contain your SharePoint data, you may end up with some of these additional properties on things. If you try to save a list or library item with one of these unrecognizable properties (to SharePoint, at least), you may get an error.
Because of this, it’s important to either:
- Delete the properties which will be seen by SharePoint as invalid before you use JSON.stringify in advance of the writes, or
- Use angular.toJson instead
I would recommend the latter, after getting bitten by my own code earlier this week. I had taken a great function Julie (@jfj1997) had adapted from Andrew Connell’s (@andrewconnell) earlier work on REST batching (See the article Make batch requests with the REST APIs for a link to AC’s examples.) and embedded it into a solution. Everything worked just fine for quite a while, and then we started noticing a few items missing when we expected them to have been loaded into a list – and it was our favorite type of bug: sporadic. It turned out that several of the items had Angular properties and were throwing errors in the batch loads. This was my fault – when I decided to use the function, I didn’t change JSON.stringify to angular.toJson. Once I did, all was right as rain.
Lesson learned for me (yet again!): be sure you understand exactly what the code you borrow really does.
Hey Marc, just a quick FYI…JSON.stringify also takes an optional “replacer” function parameter that allows you to control exactly what ends up in the resultant string. My guess would be that this is all Angular is doing. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
@David:
True. The good thing about Angular’s version is they will keep it “Angular-aware”.
M.