Skip to content

Instantly share code, notes, and snippets.

@vgrem vgrem/setLike.js

Created Dec 26, 2016
Embed
What would you like to do?
Demonstrates how to like/unlike resource via SharePoint REST API
var Reputation = Reputation || {};
Reputation = (function () {
function executeJson(options) {
var headers = options.headers || {};
headers["Accept"] = "application/json;odata=verbose";
if (options.method == "POST") {
headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
}
var ajaxOptions =
{
url: options.url,
type: options.method,
contentType: "application/json;odata=verbose",
headers: headers
};
if (options.method == "POST") {
ajaxOptions.data = JSON.stringify(options.payload);
}
return $.ajax(ajaxOptions);
}
function getListItem(webUrl, listTitle, itemId) {
var options = {
url: webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + itemId + ")",
method: "GET"
};
return executeJson(options);
}
function updateListItem(webUrl, listTitle, itemId, itemPayload) {
var options = {
url: webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + itemId + ")",
method: "POST",
headers: {
"X-HTTP-Method": "MERGE",
"If-Match": "*"
},
payload: itemPayload
};
return executeJson(options);
}
return {
setLike: function (webUrl, listTitle, itemId, setLike) {
//1.retieve existing ratings
return getListItem(webUrl, listTitle, itemId)
.then(function (data) {
//2.set like for current user
var userKey = _spPageContextInfo.userId.toString();
var likes = data.d.LikesCount;
var updated = false;
var userKeys = data.d.LikedByStringId == null ? [] : data.d.LikedByStringId.results;
var posKey = userKeys.indexOf(userKey);
if (posKey == -1) {
if (setLike) {
userKeys.push(userKey);
likes++;
updated = true;
}
}
else {
if (!setLike) {
userKeys.splice(posKey, 1);
likes--;
updated = true;
}
}
if (updated) {
var itemProperties = {
"__metadata": data.d.__metadata,
"LikedByStringId": {"results": userKeys},
LikesCount: likes
};
return updateListItem(webUrl, listTitle, itemId, itemProperties);
}
return data;
});
}
};
})();
@vgrem

This comment has been minimized.

Copy link
Owner Author

vgrem commented Dec 26, 2016

Usage

var listTitle = "Feedback";
var itemId = 1;
var webUrl = _spPageContextInfo.webServerRelativeUrl;

Reputation.setLike(webUrl, listTitle, itemId, true)
    .done(function (item) {
        console.log('Liked');
    })
    .fail(function (error) {
        console.log(JSON.stringify(error));
    });
@Fensterbank

This comment has been minimized.

Copy link

Fensterbank commented Aug 11, 2017

Hey,

thanks for this snippet!
Where du you get this property LikedByStringId?
I never saw it before (a google search brings you only to posts related to this Gist) and when I try it, SharePoint returns an error message:
The property 'LikedByStringId' does not exist on type 'SP.Data.ArticlesItem'. Make sure to only use property names that are defined by the type.

This cannot work for default SharePoint 2013 environments. :-(

@3bduuu

This comment has been minimized.

Copy link

3bduuu commented Nov 24, 2017

I had the same problem. It may be that SharePoint is just setup differently. I made a couple of minor changes and got it working:

    var Reputation = Reputation || {};

    Reputation = ( function() { function executeJson(options) {
    var headers = options.headers || {};
    headers["Accept"] = "application/json;odata=verbose";
    if (options.method == "POST") {
        headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
    }

    var ajaxOptions = {
        url: options.url,
        type: options.method,
        contentType: "application/json;odata=verbose",
        headers: headers
    };

    if (options.method == "POST") {
        ajaxOptions.data = JSON.stringify(options.payload);
    }

    return $.ajax(ajaxOptions);
}

function getListItem(webUrl, listTitle, itemId) {
    var options = {
        // had to select and expands the fields needed here otherwise i wasn't getting the LikedBy field
        url: webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + itemId + ")?$select=LikesCount,LikedBy/Id&$expand=LikedBy/Id",
        method: "GET"
    };
    return executeJson(options);
}

function updateListItem(webUrl, listTitle, itemId, itemPayload) {
    var options = {
        url: webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + itemId + ")",
        method: "POST",
        headers: {
            "X-HTTP-Method": "MERGE",
            "If-Match": "*"
        },
        payload: itemPayload
    };
    return executeJson(options);
}

return {
    setLike: function(webUrl, listTitle, itemId, setLike) {
        //1.retieve existing ratings
        return getListItem(webUrl, listTitle, itemId)
            .then(function(data) {
                //2.set like for current user
                var userKey = _spPageContextInfo.userId;
                var likes = data.d.LikesCount;
                var updated = false;
                // added mapping here to convert it from an object array to work with the rest of the code
                var userKeys = data.d.LikedBy.results == null ? [] : $.map(data.d.LikedBy.results, function(value, index) {
                    return [value.Id];
                });
                var posKey = userKeys.indexOf(userKey);
                if (posKey == -1) {
                    if (setLike) {
                        userKeys.push(userKey);
                        likes++;
                        updated = true;
                    }
                } else {
                    if (!setLike) {
                        userKeys.splice(posKey, 1);
                        likes--;
                        updated = true;
                    }
                }

                if (updated) {
                    var itemProperties = {
                        "__metadata": data.d.__metadata,
                        // Changed the name of the field because i was getting an error otherwise
                        "LikedById": { "results": userKeys },
                        "LikesCount": likes
                    };
                    return updateListItem(webUrl, listTitle, itemId, itemProperties);
                }
                return data;

            });
    }
}; })();
@Fensterbank

This comment has been minimized.

Copy link

Fensterbank commented Jan 18, 2018

@3bduuu: Thank you! With LikedById instead of LikedByStringId it works. 👍

@jasong1987

This comment has been minimized.

Copy link

jasong1987 commented Nov 2, 2018

Can someone please help - how do I include this script as part of an SPFX webpart?

@heinrich-ulbricht

This comment has been minimized.

Copy link

heinrich-ulbricht commented Mar 12, 2019

@jasong1987 Have a look at @pnp/sp/comments - accessing likes got much easier -> https://github.com/pnp/pnpjs/blob/dev/packages/sp/docs/comments-likes.md

@Sanjay12Makwana

This comment has been minimized.

Copy link

Sanjay12Makwana commented Mar 27, 2019

I am getting error as below in SharePoint online:
{"lang":"en-US","value":"The property 'LikedById' does not exist on type 'SP.Data.SitePagesItem'. Make sure to only use property names that are defined by the type."}

can some one please help me for this.

@Metroidaron

This comment has been minimized.

Copy link

Metroidaron commented May 31, 2019

Is there a way to fetch _spPageContextInfo.userId over an api fetch request? I am trying to implement some functionality in an app, but don't know how to get the _spPageContextInfo object over an api call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.