Saturday 15 June 2013

SP2013: Calling SP.ClientContext for an anonymous user causes "object doesnt support this method"

Good Morning!, and what a wonderful Saturday morning it is, the scent of strawberries are in the air!

So I've been working on a public facing 365 website lately and making a few customisations, one request I received was to have the ability for users to add an item to a "mailing list" list, and they wanted maximum portability, so I thought, perfect for the JS-CSOM!

Such a simple idea, add an item to a list, just needs one field adding in very straight forward, or so I thought, so I created the js function and hooked it up, for auth users it worked like a charm but I ran into a problem when accessing it anonymously, I got the error "object doesn't support this method" when calling a new "SP.ClientContext", its a straight forward error meaning it cant find the function in any loaded libraries, so I thought right, gotta be SP not loading sp.js, simple, add a script link in there... no luck the same error came up, then I thought right, gotta be that the method is running before SP.js is properly loaded so I used "ExecuteOrDelayUntilScriptLoaded()" to encapsulate my code and make sure it runs after the code is loaded, published the js and checked it again... no luck!

So it has to be sp.js not loading correctly, remembering the SoD SharePoint is so fond of I then tried the trusty "SP.SOD.executeFunc('sp.js', 'SP.ClientContext', addToMailingList)", and it worked perfectly!

Code:

$("#ben-mailinglist-confirm").click(function () {
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', addToMailingList)
});

function addToMailingList(metadata) {
    var metadata = $("#ben-mailinglist-email").val();
    if (metadata != "") {
        var clientContext = new SP.ClientContext("/");
        var list = clientContext.get_web().get_lists().getByTitle('MailingList');

        var itemCreateInfo = new SP.ListItemCreationInformation();
        var listItem = list.addItem(itemCreateInfo);
        listItem.set_item('Title', metadata);
        listItem.update();

        clientContext.load(listItem);
        clientContext.executeQueryAsync(
       Function.createDelegate(this, function () { $(".ben-mailinglist-success").show(); $(".ben-mailinglist-form").hide(); }),
       Function.createDelegate(this, function () { $(".ben-mailinglist-failure").show(); })
   );
    }
    else {
        // validation
    }
}

Wednesday 5 June 2013

SharePoint Online (Office365): Profile images broken / not coming up

Today I had a brilliant issue, I have a 365 authenticated site that uses profile images, these are surfaced in the "ContactFieldControl", I added profile pictures to the profiles and navigating to the mysites worked fine and the profile picture on the contactfieldcontrol worked too but then I opened it in a different browser and the profile image was broken in the webpart, that was strange I thought maybe an MS Job had deleted it so I went to the mysite and the image was there!, so I navigated back to the site and once again it shows up

So it appears if the image is loaded through the contact field webpart it shows as a broken image but if you navigate to the mysite or the image directly it worked

So how to fix it?

this issue appears to be in the first load of an image using the direct path to the image, i was hoping a cache clear or an update of the profiles would fix but but to my knowledge there is no OOTB way of fixing this so i resorted to using a dev's best friend, jQuery!

First I tried running a piece of jQuery on the page to preload the image using an ajax call but that didn't work

Then I noticed something interesting, whilst fiddling the page I saw that it also calls the following URL "/_layouts/15/userphoto.aspx?size=S&url=********", this URL links directly to the image, I thought this was interesting so I wrote a piece of jquery to take the source of the image and transform it into a URL like the one above and hey presto it worked!!

Code:
function checkProfileImages() {
    $(".ben-imgborder img").attr("src", "/_layouts/15/userphoto.aspx?size=S&url=" + $(".ben-imgborder img").attr("src"))
}