You need to sign in to do that
Don't have an account?
Dahveed
ConnectApi.ChatterFeeds.setIsMutedByMe error ConnectApi:DML currently not allowed
I am working with the chatter in apex APIs. I created a page which lists feeditems and allows the user to mute a feeditem using a checkbox. It worked great until I moved it into a visualforce component and is now giving me a ConnectApi:DML currently not allowed. Is there some kind of capability issue when using chatter ConnectApi through a visualforce component?
Below is the part of the component which parses through the wrapper to show the feed items. When I click the Mark As Read checkbox it throws the error ConnectApi:DML currently not allowed . However if I put the same code in a normal VF page it works without the error. The system.debug shows the proper Id which needs to be deleted.
<apex:repeat value="{!unreadItems}" var="fItems">
<div class="slds-media slds-comment slds-hint-parent">
<div class="slds-media__figure">
<div class="slds-avatar slds-avatar--circle slds-avatar--medium">
<a href="#void" title="{!fItems.fi.actor.Name}">
<img src="{!fItems.fi.photoUrl}" alt="{!fItems.fi.actor.Name}" />
</a>
</div>
</div>
<div class="slds-media__body">
<div class="slds-grid slds-grid--align-spread slds-has-flexi-truncate">
<p class="slds-truncate"><a href="#void" title="{!fItems.fe.header.text}">{!fItems.fe.header.text}</a></p>
<div class="slds-form-element">
<div class="slds-form-element__control">
<label class="slds-checkbox">
<apex:inputCheckbox value="{!fItems.markAsRead}" onclick="markAsRead();"/>
<span class="slds-checkbox--faux"></span>
<span class="slds-form-element__label">Mark As Read</span>
</label>
</div>
</div>
</div>
<p class="slds-text-body--small"><a href="#void" title="Click for single-item view of this post">{!fItems.fe.relativeCreatedDate}</a></p>
<div class="slds-comment__content slds-text-longform">
<p>{!fItems.fe.body.text}</p>
</div>
</div>
</div>
</apex:repeat>
<apex:actionFunction name="markAsRead" action="{!muteMsg}" reRender="nTabsPanelContainer1">
</apex:actionFunction>
Public List<FeedItemWrapper> unreadItems{get;set;}
// I populate the wrapper calling the unreadNote()
public void unreadNote(){
//unread.clear();
unreadItems = new List<FeedItemWrapper>();
ConnectApi.FeedElementPage fep =ConnectApi.ChatterFeeds.getFeedElementsFromFeed(null,ConnectApi.FeedType.Groups, 'me');
System.Debug('unread : ' + JSON.serializePretty(fep));
for(ConnectApi.FeedElement fe : fep.elements){
unreadItems.add(new FeedItemWrapper(fe));
}
}
public PageReference muteMsg(){
for(FeedItemWrapper fiw: unreadItems){
if(fiw.markAsRead == true){
System.Debug('Id being muted : ' + fiw.fi.id);
ConnectApi.ChatterFeeds.setIsMutedByMe(null,fiw.fi.id,true);
}
}
return null;
}
// Wrapper class for chatter notifications
public class FeedItemWrapper {
public Boolean markAsRead {get;set;}
public ConnectApi.FeedElement fe {get;set;}
public ConnectAPI.FeedItem fi {get;set;}
public ConnectApi.FilesCapability sourceca {get;set;}
public ConnectApi.CommentPage fecomments {get;set;}
public FeedItemWrapper (ConnectApi.FeedElement fit) {
fe = fit;
markAsRead = false;
system.debug(JSON.serializePretty(fe.header));
if (fe.feedElementType == ConnectAPI.FeedElementType.FeedItem) {
fi = (ConnectAPI.FeedItem)fe;
}
if (fit.capabilities != NULL) {
if (fit.capabilities.files != NULL) {
sourceca = fit.capabilities.files;
}
if (fit.capabilities.comments != NULL) {
fecomments = fit.capabilities.comments.page ;
}
}
}
}
Here is the exert from the debug log.
18:32:48.0 (72445222)|SYSTEM_METHOD_EXIT|[5]|FeedElement
18:32:48.0 (72696983)|HEAP_ALLOCATE|[35]|Bytes:35
18:32:48.0 (72724894)|USER_DEBUG|[35]|DEBUG|Id being muted : 0D57A000002zUrBSAU
18:32:48.0 (72732086)|STATEMENT_EXECUTE|[36]
18:32:48.0 (72737454)|HEAP_ALLOCATE|[36]|Bytes:14
18:32:48.0 (72779459)|VARIABLE_ASSIGNMENT|[EXTERNAL]|this|{"fe":"0x7da92efc","fecomments":"0xc9094dd","fi":"0x7da92efc","markAsRead":true}|0x5f26855a
18:32:48.0 (72885369)|HEAP_ALLOCATE|[36]|Bytes:953
18:32:48.0 (72894786)|SYSTEM_METHOD_ENTRY|[5]|ChatterFeeds.ChatterFeeds()
18:32:48.0 (72897158)|STATEMENT_EXECUTE|[5]
18:32:48.0 (72903311)|SYSTEM_METHOD_EXIT|[5]|ChatterFeeds
18:32:48.0 (72924236)|METHOD_ENTRY|[36]||ConnectApi.ChatterFeeds.setIsMutedByMe(String, String, Boolean)
18:32:48.0 (202377656)|METHOD_EXIT|[36]||ConnectApi.ChatterFeeds.setIsMutedByMe(String, String, Boolean)
18:32:48.0 (202399885)|SYSTEM_MODE_EXIT|false
18:32:48.0 (202499469)|FATAL_ERROR|System.LimitException: ConnectApi:DML currently not allowed Class.ConnectApi.ChatterFeeds.setIsMutedByMe: line 232, column 1 Class.SM_Notifications.muteMsg: line 36, column 1
18:32:48.0 (202514491)|CODE_UNIT_FINISHED|SM_Notifications invoke(muteMsg)
Below is the part of the component which parses through the wrapper to show the feed items. When I click the Mark As Read checkbox it throws the error ConnectApi:DML currently not allowed . However if I put the same code in a normal VF page it works without the error. The system.debug shows the proper Id which needs to be deleted.
<apex:repeat value="{!unreadItems}" var="fItems">
<div class="slds-media slds-comment slds-hint-parent">
<div class="slds-media__figure">
<div class="slds-avatar slds-avatar--circle slds-avatar--medium">
<a href="#void" title="{!fItems.fi.actor.Name}">
<img src="{!fItems.fi.photoUrl}" alt="{!fItems.fi.actor.Name}" />
</a>
</div>
</div>
<div class="slds-media__body">
<div class="slds-grid slds-grid--align-spread slds-has-flexi-truncate">
<p class="slds-truncate"><a href="#void" title="{!fItems.fe.header.text}">{!fItems.fe.header.text}</a></p>
<div class="slds-form-element">
<div class="slds-form-element__control">
<label class="slds-checkbox">
<apex:inputCheckbox value="{!fItems.markAsRead}" onclick="markAsRead();"/>
<span class="slds-checkbox--faux"></span>
<span class="slds-form-element__label">Mark As Read</span>
</label>
</div>
</div>
</div>
<p class="slds-text-body--small"><a href="#void" title="Click for single-item view of this post">{!fItems.fe.relativeCreatedDate}</a></p>
<div class="slds-comment__content slds-text-longform">
<p>{!fItems.fe.body.text}</p>
</div>
</div>
</div>
</apex:repeat>
<apex:actionFunction name="markAsRead" action="{!muteMsg}" reRender="nTabsPanelContainer1">
</apex:actionFunction>
Public List<FeedItemWrapper> unreadItems{get;set;}
// I populate the wrapper calling the unreadNote()
public void unreadNote(){
//unread.clear();
unreadItems = new List<FeedItemWrapper>();
ConnectApi.FeedElementPage fep =ConnectApi.ChatterFeeds.getFeedElementsFromFeed(null,ConnectApi.FeedType.Groups, 'me');
System.Debug('unread : ' + JSON.serializePretty(fep));
for(ConnectApi.FeedElement fe : fep.elements){
unreadItems.add(new FeedItemWrapper(fe));
}
}
public PageReference muteMsg(){
for(FeedItemWrapper fiw: unreadItems){
if(fiw.markAsRead == true){
System.Debug('Id being muted : ' + fiw.fi.id);
ConnectApi.ChatterFeeds.setIsMutedByMe(null,fiw.fi.id,true);
}
}
return null;
}
// Wrapper class for chatter notifications
public class FeedItemWrapper {
public Boolean markAsRead {get;set;}
public ConnectApi.FeedElement fe {get;set;}
public ConnectAPI.FeedItem fi {get;set;}
public ConnectApi.FilesCapability sourceca {get;set;}
public ConnectApi.CommentPage fecomments {get;set;}
public FeedItemWrapper (ConnectApi.FeedElement fit) {
fe = fit;
markAsRead = false;
system.debug(JSON.serializePretty(fe.header));
if (fe.feedElementType == ConnectAPI.FeedElementType.FeedItem) {
fi = (ConnectAPI.FeedItem)fe;
}
if (fit.capabilities != NULL) {
if (fit.capabilities.files != NULL) {
sourceca = fit.capabilities.files;
}
if (fit.capabilities.comments != NULL) {
fecomments = fit.capabilities.comments.page ;
}
}
}
}
Here is the exert from the debug log.
18:32:48.0 (72445222)|SYSTEM_METHOD_EXIT|[5]|FeedElement
18:32:48.0 (72696983)|HEAP_ALLOCATE|[35]|Bytes:35
18:32:48.0 (72724894)|USER_DEBUG|[35]|DEBUG|Id being muted : 0D57A000002zUrBSAU
18:32:48.0 (72732086)|STATEMENT_EXECUTE|[36]
18:32:48.0 (72737454)|HEAP_ALLOCATE|[36]|Bytes:14
18:32:48.0 (72779459)|VARIABLE_ASSIGNMENT|[EXTERNAL]|this|{"fe":"0x7da92efc","fecomments":"0xc9094dd","fi":"0x7da92efc","markAsRead":true}|0x5f26855a
18:32:48.0 (72885369)|HEAP_ALLOCATE|[36]|Bytes:953
18:32:48.0 (72894786)|SYSTEM_METHOD_ENTRY|[5]|ChatterFeeds.ChatterFeeds()
18:32:48.0 (72897158)|STATEMENT_EXECUTE|[5]
18:32:48.0 (72903311)|SYSTEM_METHOD_EXIT|[5]|ChatterFeeds
18:32:48.0 (72924236)|METHOD_ENTRY|[36]||ConnectApi.ChatterFeeds.setIsMutedByMe(String, String, Boolean)
18:32:48.0 (202377656)|METHOD_EXIT|[36]||ConnectApi.ChatterFeeds.setIsMutedByMe(String, String, Boolean)
18:32:48.0 (202399885)|SYSTEM_MODE_EXIT|false
18:32:48.0 (202499469)|FATAL_ERROR|System.LimitException: ConnectApi:DML currently not allowed Class.ConnectApi.ChatterFeeds.setIsMutedByMe: line 232, column 1 Class.SM_Notifications.muteMsg: line 36, column 1
18:32:48.0 (202514491)|CODE_UNIT_FINISHED|SM_Notifications invoke(muteMsg)
Best Answer chosen by Dahveed
Dahveed
For anyone dealing with this I just needed the allowDML="true" on the component. The ConnectApi counts as a DML. <apex:component controller="Notifications" allowDML="true">