Experience Editor error – After parsing a value an unexpected character was encountered: {. Path ‘scLayout’

I’ve recently been sparring with a very annoying Sitecore error. It occurs only in Experience Editor, after the Rendering Parameter properties dialog of a rendering is opened, and the user then tries to save the page.

 

sitecore error

This particular Experience Editor error is very frustrating because:
1. It blocks Content Admins from doing their work, and…
2. The fix involves manually tweaking JavaScript files on every affected Sitecore instance.

 

Fix – Take 1

I’ve been working with Sitecore 8.1 instances for the past year (from initial release to most recent update), and have been fixing the issue all over the place by following the advice from this Stack Overflow post: http://stackoverflow.com/questions/35029713/save-return-error-in-sitecore-page-editor/35443212#35443212.

That post identified the JavaScript file and function that was the source of the issue and recommended corrections, which worked perfectly. Easy peasy.

Now Sitecore 8.2 is out, and our function has received a facelift (functionlift?). The error still occurs, and the fix from above no longer helps.

 

Fix – Take 2

I found a newer Stack Exchange post — http://sitecore.stackexchange.com/a/2647 — which gave us a solution for 8.2 from Sitecore Support.

Unfortunately, it did not resolve the error for me. Could be because that post was for 8.2 Initial Release and I’m on 8.2 Update 1. But the JavaScript function where the error is happening is encoding presentation details XML, and the structure of presentation details XML has not changed, so it should be possible to support all 8+ versions with the same code.

I decided to dig in myself. Here are my findings:

Sitecore Support Code

Instructions are to go to Website/sitecore/shell/client/Sitecore/ExperienceEditor/ExperienceEditor.js and to replace the code for postServerRequest function with this updated version.

postServerRequest: function (requestType, commandContext, handler, async) {
    var token = $('input[name="__RequestVerificationToken"]').val();

    var ajaxData = unescape(JSON.stringify(commandContext));
    if (commandContext && commandContext.scLayout){
        var obj = JSON.parse(commandContext.scLayout);
        if (obj && obj.r && obj.r.d && obj.r.d.forEach){
            obj.r.d.forEach(function(x,y){
                if (x.r && x.r.forEach) {
                    x.r.forEach(function(a,z){
                        var val = a["@par"];
                        if (val && val.length > 0){
                            ajaxData = ajaxData.replace(unescape(val), val);
                        }                       
                    });
                }
            });
        }
    }

    jQuery.ajax({
        url: "/-/speak/request/v1/expeditor/" + requestType,
        data: {
            __RequestVerificationToken: token,
            data: ajaxData
        },
        success: handler,
        type: "POST",
        async: async != undefined ? async : false
    });
}

 

Identity Crisis

It turns out that the type of obj.r.d varies depending on whether your page is using one or multiple device layouts. This property can be either an object or an array.

Seriously, check it out:

This is my page when only the “Default” device has a layout..
experience editor js_ code
..and after a second layout for the “Print” device is added.
experience editor js code

 

That’s why the code from Sitecore support didn’t work for me. That version depends on obj.r.d being an array since it calls obj.r.d.forEach. We typically use a single device layout for our pages (there’s no need for a Print layout since custom print displays can be handled with CSS media queries), so obj.r.d is an object and obj.r.d.forEach is undefined. As a result, the check “if (obj && obj.r && obj.r.d && obj.r.d.forEach)” just fails silently and the dreaded Experience Editor red ribbon of doom appears.

 

Fix – 3rd Time’s A Charm

Here is my version of the fix. It normalizes the obj.r.d property, so it won’t matter how many layouts you have.

postServerRequest: function (requestType, commandContext, handler, async) {
  
	function normalizeDeviceProp(d) {
		if (typeof(d) !== "object")
			throw new Error("Unexpected presentation details XML: cannot find device property");
	
		if (d instanceof Array)
			return d;
	
		var normalized = [];
		normalized.push(d);
		return normalized;
	}
	  
    var token = $('input[name="__RequestVerificationToken"]').val();

    // Custom Brainjocks code to fix Experience Editor error.
    var ajaxData = unescape(JSON.stringify(commandContext));
    if (commandContext && commandContext.scLayout) {
        var obj = JSON.parse(commandContext.scLayout);
	  if (obj && obj.r) {
		  normalizeDeviceProp(obj.r.d).forEach(function (d) {
			  if (d.r instanceof Array) {
				  d.r.forEach(function (r) {
					  var val = r["@par"];
						if (val && val.length > 0) {
							ajaxData = ajaxData.replace(unescape(val), val);
						}
				  });
			  }
                
            });
        }
    }

    jQuery.ajax({
        url: "/-/speak/request/v1/expeditor/" + requestType,
        data: {
            __RequestVerificationToken: token,
            data: ajaxData
        },
        success: handler,
        type: "POST",
        async: async != undefined ? async : false
    });
}

 

If you have any feedback or questions on resolving this Experience Editor error, please let me know in the comments. Thanks!

Anastasiya Flynn

I am a front-to-back, full-stack developer with 5 years of experience in the CMS world – Sitecore and beyond. I excel in the technical aspects of software development and architecture but, personally, I really enjoy working on UI development. I am capable of detaching from my developer brain and analyzing the output from a non-technical perspective, anticipating the challenges end users will experience.

My career started out in the support department, and I keep the lessons I learned there close to my heart. When working on a project, my first priority is to amaze our customer. My second priority is to enforce practices that will make the code a pleasure to maintain. I am not the type of person who is satisfied with producing software that merely works – I am emotionally connected. I want the code to be organized and beautiful, and I am personally invested in its success, usability and longevity. Learn more about Anastasiya Flynn.

Add a Comment

Your email address will not be published. Required fields are marked *

Or request call back