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 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 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 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 Fensterbank commented Jan 18, 2018

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

@jasong1987

This comment has been minimized.

Copy link

@jasong1987 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 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 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 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