Uncaught TypeError: Cannot read property 'get_current' of undefined
-
10-12-2019 - |
Question
this one is weird I hope somebody can help me.
I created a custom action for a callout on a document library. I added the javascript code in a code snippet webpart on top of the document library default view.
When I click on the left navigation menu to go to the library, the code throws this exception when I click on the 3 dots.
Uncaught TypeError: Cannot read property 'get_current' of undefined
If I press Ctrl + F5, the code works fine.
<script type="text/javascript">
SP.SOD.executeFunc("callout.js", "Callout", function () {
IsCurrentUserMemberOfGroup("Approvers", function(isSuccess){
if(isSuccess){
var itemCtx = {};
itemCtx.Templates = {};
itemCtx.BaseViewID = 'Callout';
// Define the list template type
itemCtx.ListTemplateType = 101;
itemCtx.Templates.Footer = function (itemCtx) {
return CalloutRenderFooterTemplate(itemCtx, AddCustomCompleteAction, true);
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);
}
});
});
function AddCustomCompleteAction (renderCtx, calloutActionMenu) {
var Status = renderCtx.CurrentItem.Status;
if(renderCtx.CurrentItem.ContentType=='Bill Cycle' && Status=='') {
calloutActionMenu.addAction (new CalloutAction ({
text: 'COMPLETE',
tooltip: 'This action will set status to Complete, this action cant be rolled back. Only click once the action can take a few seconds to complete.',
onClickCallback: function() {UpdateBillCycleStatusToCompleted(renderCtx.CurrentItem.ID);}
}));
}
// Show the default document library actions
CalloutOnPostRenderTemplate(renderCtx, calloutActionMenu);
// Show the follow action
calloutActionMenu.addAction(new CalloutAction({
text: Strings.STS.L_CalloutFollowAction,
tooltip: Strings.STS.L_CalloutFollowAction_Tooltip,
onClickCallback: function (calloutActionClickEvent, calloutAction) {
var callout = GetCalloutFromRenderCtx(renderCtx);
if (!(typeof(callout) === 'undefined' || callout === null))
callout.close();
SP.SOD.executeFunc('followingcommon.js', 'FollowSelectedDocument', function() { FollowSelectedDocument(renderCtx); });
}
}));
}
function UpdateBillCycleStatusToCompleted(itemId) {
var clientContext = new SP.ClientContext.get_current();
var oList = clientContext.get_web().get_lists().getByTitle('Cycles');
this.oListItem = oList.getItemById(itemId);
oListItem.set_item('Status', 'Completed');
oListItem.update();
clientContext.executeQueryAsync(Function.createDelegate(this, this.StatusCompletedSucceeded), Function.createDelegate(this, this.StatusCompletedFailed));
}
function StatusCompletedSucceeded() {
alert(' set to completed succeeded');
window.location.reload(true);
}
function StatusCompletedFailed(sender, args) {
alert(' update failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
function IsCurrentUserMemberOfGroup(groupName, callback) {
var currentContext = new SP.ClientContext.get_current();
var currentWeb = currentContext.get_web();
var currentUser = currentContext.get_web().get_currentUser();
currentContext.load(currentUser);
var allGroups = currentWeb.get_siteGroups();
currentContext.load(allGroups);
var group = allGroups.getByName(groupName);
currentContext.load(group);
var groupUsers = group.get_users();
currentContext.load(groupUsers);
currentContext.executeQueryAsync(OnSuccess,OnFailure);
function OnSuccess(sender, args) {
var userInGroup = false;
var groupUserEnumerator = groupUsers.getEnumerator();
while (groupUserEnumerator.moveNext()) {
var groupUser = groupUserEnumerator.get_current();
if (groupUser.get_id() == currentUser.get_id()) {
userInGroup = true;
break;
}
}
callback(userInGroup);
}
function OnFailure(sender, args) {
callback(false);
}
}
</script>
Solution 2
fixed with this
$(document).ready(function () { ExecuteOrDelayUntilScriptLoaded(CustomAction, "sp.js"); });
function CustomAction()
{
//Your Code
}
OTHER TIPS
Since you are using SP.ClientContext
in CSR, make sure the SharePoint script file 'sp.js' is loaded before your rendering code runs:
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){
//Your code goes here...
});
This works for me when I am using WorkflowServices. It should work in your case as well:
ExecuteOrDelayUntilScriptLoaded(function () {
ExecuteOrDelayUntilScriptLoaded(function () {
SP.SOD.registerSod('SP.ClientContext', SP.Utilities.Utility.getLayoutsPageUrl('sp.js'));
SP.SOD.registerSod('SP.WorkflowServices.WorkflowServicesManager', SP.Utilities.Utility.getLayoutsPageUrl('SP.WorkflowServices.js'));
SP.SOD.loadMultiple(['SP.ClientContext', 'SP.WorkflowServices.WorkflowServicesManager'], function () {
var context = SP.ClientContext.get_current();
var web = context.get_web();
var servicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(context, web);
var instanceService = servicesManager.getWorkflowInstanceService();
});
}, "sp.js");
}, "sp.runtime.js");
Elaborating more on Vadim solution:
function retrieveWebSite() {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){
var clientContext = new SP.ClientContext.get_current();
this.oWebsite = clientContext.get_web();
clientContext.load(this.oWebsite);
clientContext.executeQueryAsync(
Function.createDelegate(this, this.onQuerySucceeded),
Function.createDelegate(this, this.onQueryFailed)
);
});
}
function onQuerySucceeded(sender, args) {
alert('Title: ' + this.oWebsite.get_title() +
' Description: ' + this.oWebsite.get_description());
}
function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() +
'\n' + args.get_stackTrace());
}
In HTML
<input type="button" onclick="retrieveWebSite()" value="Click"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange