-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
8Questions
-
15Replies
Error in test class for batch apex sending emails to users
Hi,
I have written batch to send emails to users not logged in more than 20 days. it is working when I use schedular with batch limit 10.
But when I am trying to write test class I am getting below error:
"System.UnexpectedException: No more than one executeBatch can be called from within a test method. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation."
--- my batch --
global class SendEmailtoNonActiveUsersBatch implements database.Batchable<sObject> {
Exception[] errors = new Exception[0];
global String query;
global Database.QueryLocator start(Database.BatchableContext bc) {
string query = 'SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= \'Employee\' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC ';
return database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<User> scope){
system.debug('Scope size' +scope.size());
try{
String currentUserLink = URL.getSalesforceBaseUrl().toExternalForm() + '/';
if(scope.size() >0){
for(user u: scope){
if(u.IsEmailSendToNonActive__c != true){
u.IsEmailSendToNonActive__c = true;
string[] toAddress = new string[] {u.Email};
string subject = 'Notification Of User Deactivation';
string plainBody = 'TEST'
SendEmail(toAddress,subject, plainBody, null, null );
update u;
}
}
}
}
catch(exception e){
errors.add(e);
}
}
global void finish(Database.BatchableContext bc){
//Admins email addresses
List<string> emailAdd = new List<string>();
for(AdminsEmailList__c emad : AdminsEmailList__c.getAll().values())
{
system.debug('emad.Email__c:'+emad.Email__c);
emailAdd.add(emad.Email__c);
}
List<AggregateResult> numberOfRows = [Select count(id) from user where IsEmailSendToNonActive__c=True and lastmodifieddate = today];
integer numRow = (integer)numberOfRows[0].get('expr0');
AsyncApexJob a = [SELECT Id,Status,JobType,NumberOfErrors,JobItemsProcessed,TotalJobItems,CompletedDate,ExtendedStatus
FROM AsyncApexJob WHERE Id =:BC.getJobId()];
//check for errors if no error then proceed
string errorString;
for(Exception s: errors)
{
errorString = errorString + s.getMessage();
}
if(!errors.isEmpty()) {
string errSub = 'Error(s) occurred during sending emails to Non Active user batch process.';
string errBody = 'below is the error details: \n\n'+errorString;
SendEmail(emailAdd, errSub, errBody, null, null);
}
}
public void SendEmail(List<string> toEmailAdd, string subject, string body, string attchmentName, string attachment){
system.debug('toEmailAdd::'+toEmailAdd);
if(toEmailAdd != null && !toEmailAdd.isEmpty()){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(toEmailAdd);
mail.setSubject(subject);
mail.setSaveAsActivity(false);
mail.setPlainTextBody(body);
Messaging.sendEmail(new Messaging.Email[] { mail });
}
}
}
--- Schedular --
global class ScheduleSendEmailToNonActiveUsers implements Schedulable{
global void execute(SchedulableContext sc){
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s, 10);
}
}
--- TEST CLASS -----
@isTest
public class SendEmailtoNonActiveUsersBatch_Test {
@IsTest(seeAllData=true)
public static void SendEmailTest_positive()
{
User us = [Select id from User where Id = :UserInfo.getUserId()];
System.runAs(us)
{
List<user> uu = [SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= 'Employee' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC Limit 10];
Test.startTest();
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s);
Test.stopTest();
}
}
}
Another observation: test class should execute DML query menstioned in test class(resulte records 10). But when I run the test class it take query mentioned in batch apex(result records 162).
I have written batch to send emails to users not logged in more than 20 days. it is working when I use schedular with batch limit 10.
But when I am trying to write test class I am getting below error:
"System.UnexpectedException: No more than one executeBatch can be called from within a test method. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation."
--- my batch --
global class SendEmailtoNonActiveUsersBatch implements database.Batchable<sObject> {
Exception[] errors = new Exception[0];
global String query;
global Database.QueryLocator start(Database.BatchableContext bc) {
string query = 'SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= \'Employee\' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC ';
return database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<User> scope){
system.debug('Scope size' +scope.size());
try{
String currentUserLink = URL.getSalesforceBaseUrl().toExternalForm() + '/';
if(scope.size() >0){
for(user u: scope){
if(u.IsEmailSendToNonActive__c != true){
u.IsEmailSendToNonActive__c = true;
string[] toAddress = new string[] {u.Email};
string subject = 'Notification Of User Deactivation';
string plainBody = 'TEST'
SendEmail(toAddress,subject, plainBody, null, null );
update u;
}
}
}
}
catch(exception e){
errors.add(e);
}
}
global void finish(Database.BatchableContext bc){
//Admins email addresses
List<string> emailAdd = new List<string>();
for(AdminsEmailList__c emad : AdminsEmailList__c.getAll().values())
{
system.debug('emad.Email__c:'+emad.Email__c);
emailAdd.add(emad.Email__c);
}
List<AggregateResult> numberOfRows = [Select count(id) from user where IsEmailSendToNonActive__c=True and lastmodifieddate = today];
integer numRow = (integer)numberOfRows[0].get('expr0');
AsyncApexJob a = [SELECT Id,Status,JobType,NumberOfErrors,JobItemsProcessed,TotalJobItems,CompletedDate,ExtendedStatus
FROM AsyncApexJob WHERE Id =:BC.getJobId()];
//check for errors if no error then proceed
string errorString;
for(Exception s: errors)
{
errorString = errorString + s.getMessage();
}
if(!errors.isEmpty()) {
string errSub = 'Error(s) occurred during sending emails to Non Active user batch process.';
string errBody = 'below is the error details: \n\n'+errorString;
SendEmail(emailAdd, errSub, errBody, null, null);
}
}
public void SendEmail(List<string> toEmailAdd, string subject, string body, string attchmentName, string attachment){
system.debug('toEmailAdd::'+toEmailAdd);
if(toEmailAdd != null && !toEmailAdd.isEmpty()){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(toEmailAdd);
mail.setSubject(subject);
mail.setSaveAsActivity(false);
mail.setPlainTextBody(body);
Messaging.sendEmail(new Messaging.Email[] { mail });
}
}
}
--- Schedular --
global class ScheduleSendEmailToNonActiveUsers implements Schedulable{
global void execute(SchedulableContext sc){
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s, 10);
}
}
--- TEST CLASS -----
@isTest
public class SendEmailtoNonActiveUsersBatch_Test {
@IsTest(seeAllData=true)
public static void SendEmailTest_positive()
{
User us = [Select id from User where Id = :UserInfo.getUserId()];
System.runAs(us)
{
List<user> uu = [SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= 'Employee' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC Limit 10];
Test.startTest();
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s);
Test.stopTest();
}
}
}
Another observation: test class should execute DML query menstioned in test class(resulte records 10). But when I run the test class it take query mentioned in batch apex(result records 162).
- Sisodia Saurabh
- June 27, 2019
- Like
- 0
- Continue reading or reply
lightning datatable columns name getting truncated, need to define fix length to columns and horizontal scroll bar
Hi All,
I have created a component to should contact column on account. I have to show records in lightning: datatable with 17 columns. When I increase the number of columns, component truncate the headers and try to fit all the columns in component default width.
Expected output: component should not trim and wrap the header and should all 17 columns with scroll bar.
Below is the screen shot. highlited column is: LEADSOURCE (component wrapped it)
Thanks.
I have created a component to should contact column on account. I have to show records in lightning: datatable with 17 columns. When I increase the number of columns, component truncate the headers and try to fit all the columns in component default width.
Expected output: component should not trim and wrap the header and should all 17 columns with scroll bar.
Below is the screen shot. highlited column is: LEADSOURCE (component wrapped it)
Thanks.
- Sisodia Saurabh
- December 06, 2018
- Like
- 0
- Continue reading or reply
lightning datatable onsort event not firing
Hello Everyone,
I am trying to impelement column sorting. When component loads it sorts the default coulmns value but Lightning: datatable "Onsort" event is not firing, I am getting column names as text only , nothing else(like arrow or something) to click for sorting event firing.
below is my code:
TestAccountComponent
<aura:attribute name="sortedBy" type="String" default="LastName"/>
<aura:attribute name="sortedDirection" type="String" default="asc"/>
<aura:attribute name="defaultSortDirection" type="String"/>
<lightning:datatable minColumnWidth="400px"
data="{! v.Contact }"
columns="{! v.Columns }"
keyField="Id"
hideCheckboxColumn="true"
onsort="{!c.updateColumnSorting}"
sortedBy="{!v.sortedBy}"
sortedDirection="{!v.sortedDirection}"
defaultSortDirection="{! v.defaultSortDirection }"/>
Controller:
getContact : function(component, event, helper) {
debugger;
helper.getStatus(component);
helper.getLeadSourceOpt(component);
component.set("v.Columns", [
{label:"FirstName", fieldName:"FirstName", type:"text"},
{label:"LastName", fieldName:"LastName", type:"text"},
{label:"Phone", fieldName:"Phone", type:"text"},
{label:"Email", fieldName:"Email", type:"text"},
{label:"Contact_Status__c", fieldName:"Contact_Status__c", type:"text"},
{label:"LeadSource", fieldName:"LeadSource", type:"text"}
]);
var rcdID = component.get("v.recordId");
var action = component.get("c.fetchContactList");
action.setParams({
recordId : rcdID
});
action.setCallback(this, function(data) {
var state = data.getState();
if (state === "SUCCESS") {
component.set("v.Contact", data.getReturnValue());
helper.sortData(component, component.get("v.sortedBy"), component.get("v.sortedDirection"));
}
});
$A.enqueueAction(action);
},
updateColumnSorting : function (cmp, event, helper) {
var fieldName = event.getParam('fieldName');
// var sortDirection = event.getParam('sortDirection');
var sortDirection = component.get("v.sortDirection") == 'asc' ? 'desc' : 'asc';
cmp.set("v.sortedBy", fieldName);
cmp.set("v.sortedDirection", sortDirection);
helper.sortData(cmp, fieldName, sortDirection);
}
Helper::
sortData : function (cmp, fieldname, sortDirection) {
debugger;
var data = cmp.get("v.Contact");
var reverse = sortDirection !== 'asc';
data.sort(this.sortBy(fieldname, reverse))
cmp.set("v.Contact", data);
},
sortBy : function (field, reverse, primer) {
var key = primer ?
function(x) {return primer(x[field])} :
function(x) {return x[field]};
reverse = !reverse ? 1 : -1;
return function (a, b) {
return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
}
}
Apex class::
@AuraEnabled
public static List<contact> fetchContactList(Id recordId)
{
system.debug('fetchContactList');
return [Select id, FirstName, LastName, Phone, Email, Contact_Status__c, LeadSource from Contact where AccountId=:recordId];
}
Thanks.
Saurabh Sisodia
I am trying to impelement column sorting. When component loads it sorts the default coulmns value but Lightning: datatable "Onsort" event is not firing, I am getting column names as text only , nothing else(like arrow or something) to click for sorting event firing.
below is my code:
TestAccountComponent
<aura:attribute name="sortedBy" type="String" default="LastName"/>
<aura:attribute name="sortedDirection" type="String" default="asc"/>
<aura:attribute name="defaultSortDirection" type="String"/>
<lightning:datatable minColumnWidth="400px"
data="{! v.Contact }"
columns="{! v.Columns }"
keyField="Id"
hideCheckboxColumn="true"
onsort="{!c.updateColumnSorting}"
sortedBy="{!v.sortedBy}"
sortedDirection="{!v.sortedDirection}"
defaultSortDirection="{! v.defaultSortDirection }"/>
Controller:
getContact : function(component, event, helper) {
debugger;
helper.getStatus(component);
helper.getLeadSourceOpt(component);
component.set("v.Columns", [
{label:"FirstName", fieldName:"FirstName", type:"text"},
{label:"LastName", fieldName:"LastName", type:"text"},
{label:"Phone", fieldName:"Phone", type:"text"},
{label:"Email", fieldName:"Email", type:"text"},
{label:"Contact_Status__c", fieldName:"Contact_Status__c", type:"text"},
{label:"LeadSource", fieldName:"LeadSource", type:"text"}
]);
var rcdID = component.get("v.recordId");
var action = component.get("c.fetchContactList");
action.setParams({
recordId : rcdID
});
action.setCallback(this, function(data) {
var state = data.getState();
if (state === "SUCCESS") {
component.set("v.Contact", data.getReturnValue());
helper.sortData(component, component.get("v.sortedBy"), component.get("v.sortedDirection"));
}
});
$A.enqueueAction(action);
},
updateColumnSorting : function (cmp, event, helper) {
var fieldName = event.getParam('fieldName');
// var sortDirection = event.getParam('sortDirection');
var sortDirection = component.get("v.sortDirection") == 'asc' ? 'desc' : 'asc';
cmp.set("v.sortedBy", fieldName);
cmp.set("v.sortedDirection", sortDirection);
helper.sortData(cmp, fieldName, sortDirection);
}
Helper::
sortData : function (cmp, fieldname, sortDirection) {
debugger;
var data = cmp.get("v.Contact");
var reverse = sortDirection !== 'asc';
data.sort(this.sortBy(fieldname, reverse))
cmp.set("v.Contact", data);
},
sortBy : function (field, reverse, primer) {
var key = primer ?
function(x) {return primer(x[field])} :
function(x) {return x[field]};
reverse = !reverse ? 1 : -1;
return function (a, b) {
return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
}
}
Apex class::
@AuraEnabled
public static List<contact> fetchContactList(Id recordId)
{
system.debug('fetchContactList');
return [Select id, FirstName, LastName, Phone, Email, Contact_Status__c, LeadSource from Contact where AccountId=:recordId];
}
Thanks.
Saurabh Sisodia
- Sisodia Saurabh
- December 05, 2018
- Like
- 0
- Continue reading or reply
have to create custom login for new community and redirect it to skilljar
Hello everyone,
I have to create a custom Login page for our new community(TrainingCenter). Tastk is that this Login page should Authenticate username and paswword of external users and the redirect it to skilljar(which is connected app with SSO on).
Any Idea how to implement this.
Thanks
I have to create a custom Login page for our new community(TrainingCenter). Tastk is that this Login page should Authenticate username and paswword of external users and the redirect it to skilljar(which is connected app with SSO on).
Any Idea how to implement this.
Thanks
- Sisodia Saurabh
- April 04, 2018
- Like
- 0
- Continue reading or reply
Need to validate fields on default details tab then redirect to new page using Lightning component
Hi All,
I need to validate couple of fields from details tab of a case. if fields are not empty/null then Click on the component button to redirect the page. I know the 2nd part of redirecting but I want to know how can I validate fields on the component click.
Below is the logic which I was trying but I am pretty sure it is not correct way:
Controller
caseValidation : function(component, event, helper){
debugger;
var caseId = component.get("v.recordId");
var action = component.get("c.caseValidationList");
action.setParams({
Id : caseId
});
action.setCallback(this, function(response){
var state = response.getState();
var cv = response.getReturnValue();
alert(response.getReturnValue());
var csonevar;
if (state === "SUCCESS") {
for(var c in cv)
{
csonevar = c.CSOne_Case_Number__c;
}
alert(csonevar);
}
});
$A.enqueueAction(action);
}
Classe returning query
@AuraEnabled
public static list<case> caseValidationList(Id Id)
{
system.debug('caseId:'+Id);
List<case> cc = new List<case>();
if(Id != null || Id != '')
{
cc = [Select CSOne_Case_Number__c, OwnerIsQueue__c,Status from case where Id=: Id];
}
return cc;
}
Thanks in advance
~Srb
I need to validate couple of fields from details tab of a case. if fields are not empty/null then Click on the component button to redirect the page. I know the 2nd part of redirecting but I want to know how can I validate fields on the component click.
Below is the logic which I was trying but I am pretty sure it is not correct way:
Controller
caseValidation : function(component, event, helper){
debugger;
var caseId = component.get("v.recordId");
var action = component.get("c.caseValidationList");
action.setParams({
Id : caseId
});
action.setCallback(this, function(response){
var state = response.getState();
var cv = response.getReturnValue();
alert(response.getReturnValue());
var csonevar;
if (state === "SUCCESS") {
for(var c in cv)
{
csonevar = c.CSOne_Case_Number__c;
}
alert(csonevar);
}
});
$A.enqueueAction(action);
}
Classe returning query
@AuraEnabled
public static list<case> caseValidationList(Id Id)
{
system.debug('caseId:'+Id);
List<case> cc = new List<case>();
if(Id != null || Id != '')
{
cc = [Select CSOne_Case_Number__c, OwnerIsQueue__c,Status from case where Id=: Id];
}
return cc;
}
Thanks in advance
~Srb
- Sisodia Saurabh
- January 16, 2018
- Like
- 0
- Continue reading or reply
passing parameter to URL in lightning component
Hi,
It was really simple to open URL in new window with passing parameters and some Validations using salesforce classic Onclick Java. for example:
if({!ISBLANK( Account.CSOne_Case_Number__c )})
{
window.open('https://.na29.visual.force.com/apex/Relationship360?rId={!Account.Gainsight_Relationship_ID__c}');
}
Now we are moving to Salesforce Lightning and As Onclick Javascript is not supported. can someone please let me know how can I achieve this in Lightning.
Thanks in advance.
Saurabh Sisodia
It was really simple to open URL in new window with passing parameters and some Validations using salesforce classic Onclick Java. for example:
if({!ISBLANK( Account.CSOne_Case_Number__c )})
{
window.open('https://.na29.visual.force.com/apex/Relationship360?rId={!Account.Gainsight_Relationship_ID__c}');
}
Now we are moving to Salesforce Lightning and As Onclick Javascript is not supported. can someone please let me know how can I achieve this in Lightning.
Thanks in advance.
Saurabh Sisodia
- Sisodia Saurabh
- January 11, 2018
- Like
- 0
- Continue reading or reply
Future method cannot be called from a future or batch method: Error
Hi,
I am getting this error while I am trying to update contact which are associated to user objects.
trigger CommunityLoginOnContactTrigger on User (after update) {
for(User u: trigger.new)
{
system.debug('USer trigger got triggered');
if(system.isFuture()) return;
if(u.ContactId != null)
{
if(u.LastLoginDate__c != null)
{
UpdateContactFromTestUser.updateContacts(u.ContactId, u.LastLoginDate__c);
}
}
}
}
global class UpdateContactFromTestUser {
@future
public static void updateContacts(String userId, Datetime Lastlogin) {
if (userId!=null && userId != '') {
Contact c = [ Select Last_Community_Login__c,Community_Category__c from Contact where id =:userId];
if(c.Last_Community_Login__c != Lastlogin)
{
c.Last_Community_Login__c = Lastlogin;
update c;
}
}
}
}
I am getting this error while I am trying to update contact which are associated to user objects.
trigger CommunityLoginOnContactTrigger on User (after update) {
for(User u: trigger.new)
{
system.debug('USer trigger got triggered');
if(system.isFuture()) return;
if(u.ContactId != null)
{
if(u.LastLoginDate__c != null)
{
UpdateContactFromTestUser.updateContacts(u.ContactId, u.LastLoginDate__c);
}
}
}
}
global class UpdateContactFromTestUser {
@future
public static void updateContacts(String userId, Datetime Lastlogin) {
if (userId!=null && userId != '') {
Contact c = [ Select Last_Community_Login__c,Community_Category__c from Contact where id =:userId];
if(c.Last_Community_Login__c != Lastlogin)
{
c.Last_Community_Login__c = Lastlogin;
update c;
}
}
}
}
- Sisodia Saurabh
- September 01, 2017
- Like
- 0
- Continue reading or reply
Need solution to open VF page in new tab
Hi All,
I want to implement a functionality in which when user click on Item it should display information in new Tab instead of new page.
My scenario description:
Name First Name Last Name Phone NoStart Date DOB Prog Lang
Emp-0034 Runthistime
<apex:column headerValue="Name" >
<apex:outputLink value="/apex/Emp_DisplayForm?id={!a.id}"> {!a.name}</apex:outputLink>
</apex:column>
On click of Emp-0034. it opens item in my custom Emp_DisplayForm as new page. But I want it to be open in new tab?
Thanks.
Srb
I want to implement a functionality in which when user click on Item it should display information in new Tab instead of new page.
My scenario description:
Name First Name Last Name Phone NoStart Date DOB Prog Lang
Emp-0034 Runthistime
<apex:column headerValue="Name" >
<apex:outputLink value="/apex/Emp_DisplayForm?id={!a.id}"> {!a.name}</apex:outputLink>
</apex:column>
On click of Emp-0034. it opens item in my custom Emp_DisplayForm as new page. But I want it to be open in new tab?
Thanks.
Srb
- Sisodia Saurabh
- June 03, 2016
- Like
- 0
- Continue reading or reply
Error in lightning Web Component?
Dear Team ,
I created LWC having search functionality but m getting error plz have a look on image and my code
Plz help me to solve this error
Thanks & Regards
Sachin Bhalerao
I created LWC having search functionality but m getting error plz have a look on image and my code
<template> <div class="slds-m-around_medium"> <div class="slds-m-bottom_small"> <lightning-input type="text" value={sVal} label="Contact Name" onchange={updateSeachKey} ></lightning-input> </div> <lightning-button label="Search" onclick={handleSearch} variant="brand"></lightning-button> <!-- custom data table(with SLDS style) to display contact list --> <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-m-top_small"> <thead> <tr class="slds-line-height_reset"> <th class="" scope="col"> <div class="slds-truncate" title="First Name">First Name</div> </th> <th class="" scope="col"> <div class="slds-truncate" title="Last Name">Last Name</div> </th> <th class="" scope="col"> <div class="slds-truncate" title="Phone">Phone</div> </th> <th class="" scope="col"> <div class="slds-truncate" title="Email">Email</div> </th> </tr> </thead> <tbody> <!--iterate all contact records using for-each iteration --> <template for:each={contacts} for:item="contact"> <tr class="slds-hint-parent" key={contact.Id}> <td> <div class="slds-truncate">{contact.FirstName}</div> </td> <td> <div class="slds-truncate">{contact.LastName}</div> </td> <td> <div class="slds-truncate"> <lightning-formatted-phone value={contact.Phone} ></lightning-formatted-phone> </div> </td> <td> <div class="slds-truncate"> <lightning-formatted-email value={contact.Email} ></lightning-formatted-email> </div> </td> </tr> </template> </tbody> </table> </div> </template> import { LightningElement,track} from 'lwc'; // import server side apex class method import getContactList from '@salesforce/apex/customSearchController.getContactList'; // import standard toast event import {ShowToastEvent} from 'lightning/platformShowToastEvent' export default class customSearch extends LightningElement { //@track: Marks a property for internal monitoring. A template or function using- //this property forces a component to rerender when the property’s value changes. @track contacts; sVal = ''; // update sVal var when input field value change updateSeachKey(event) { this.sVal = event.target.value; } // call apex method on button click handleSearch() { // if search input value is not blank then call apex method, else display error msg if (this.sVal !== '') { getContactList({ searchKey: this.sVal }) .then(result => { // set @track contacts variable with return contact list from server this.contacts = result; }) .catch(error => { // display server exception in toast msg const event = new ShowToastEvent({ title: 'Error', variant: 'error', message: error.body.message, }); this.dispatchEvent(event); // reset contacts var with null this.contacts = null; }); } else { // fire toast event if input field is blank const event = new ShowToastEvent({ variant: 'error', message: 'Search text missing..', }); this.dispatchEvent(event); } } } <?xml version="1.0" encoding="UTF-8"?> <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="customSearch"> <apiVersion>47.0</apiVersion> <isExposed>true</isExposed> <targets> <target>lightning__AppPage</target> <target>lightning__RecordPage</target> <target>lightning__HomePage</target> </targets> </LightningComponentBundle>
Plz help me to solve this error
Thanks & Regards
Sachin Bhalerao
- Sachin Bhalerao 17
- November 29, 2019
- Like
- 0
- Continue reading or reply
Error in test class for batch apex sending emails to users
Hi,
I have written batch to send emails to users not logged in more than 20 days. it is working when I use schedular with batch limit 10.
But when I am trying to write test class I am getting below error:
"System.UnexpectedException: No more than one executeBatch can be called from within a test method. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation."
--- my batch --
global class SendEmailtoNonActiveUsersBatch implements database.Batchable<sObject> {
Exception[] errors = new Exception[0];
global String query;
global Database.QueryLocator start(Database.BatchableContext bc) {
string query = 'SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= \'Employee\' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC ';
return database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<User> scope){
system.debug('Scope size' +scope.size());
try{
String currentUserLink = URL.getSalesforceBaseUrl().toExternalForm() + '/';
if(scope.size() >0){
for(user u: scope){
if(u.IsEmailSendToNonActive__c != true){
u.IsEmailSendToNonActive__c = true;
string[] toAddress = new string[] {u.Email};
string subject = 'Notification Of User Deactivation';
string plainBody = 'TEST'
SendEmail(toAddress,subject, plainBody, null, null );
update u;
}
}
}
}
catch(exception e){
errors.add(e);
}
}
global void finish(Database.BatchableContext bc){
//Admins email addresses
List<string> emailAdd = new List<string>();
for(AdminsEmailList__c emad : AdminsEmailList__c.getAll().values())
{
system.debug('emad.Email__c:'+emad.Email__c);
emailAdd.add(emad.Email__c);
}
List<AggregateResult> numberOfRows = [Select count(id) from user where IsEmailSendToNonActive__c=True and lastmodifieddate = today];
integer numRow = (integer)numberOfRows[0].get('expr0');
AsyncApexJob a = [SELECT Id,Status,JobType,NumberOfErrors,JobItemsProcessed,TotalJobItems,CompletedDate,ExtendedStatus
FROM AsyncApexJob WHERE Id =:BC.getJobId()];
//check for errors if no error then proceed
string errorString;
for(Exception s: errors)
{
errorString = errorString + s.getMessage();
}
if(!errors.isEmpty()) {
string errSub = 'Error(s) occurred during sending emails to Non Active user batch process.';
string errBody = 'below is the error details: \n\n'+errorString;
SendEmail(emailAdd, errSub, errBody, null, null);
}
}
public void SendEmail(List<string> toEmailAdd, string subject, string body, string attchmentName, string attachment){
system.debug('toEmailAdd::'+toEmailAdd);
if(toEmailAdd != null && !toEmailAdd.isEmpty()){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(toEmailAdd);
mail.setSubject(subject);
mail.setSaveAsActivity(false);
mail.setPlainTextBody(body);
Messaging.sendEmail(new Messaging.Email[] { mail });
}
}
}
--- Schedular --
global class ScheduleSendEmailToNonActiveUsers implements Schedulable{
global void execute(SchedulableContext sc){
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s, 10);
}
}
--- TEST CLASS -----
@isTest
public class SendEmailtoNonActiveUsersBatch_Test {
@IsTest(seeAllData=true)
public static void SendEmailTest_positive()
{
User us = [Select id from User where Id = :UserInfo.getUserId()];
System.runAs(us)
{
List<user> uu = [SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= 'Employee' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC Limit 10];
Test.startTest();
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s);
Test.stopTest();
}
}
}
Another observation: test class should execute DML query menstioned in test class(resulte records 10). But when I run the test class it take query mentioned in batch apex(result records 162).
I have written batch to send emails to users not logged in more than 20 days. it is working when I use schedular with batch limit 10.
But when I am trying to write test class I am getting below error:
"System.UnexpectedException: No more than one executeBatch can be called from within a test method. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation."
--- my batch --
global class SendEmailtoNonActiveUsersBatch implements database.Batchable<sObject> {
Exception[] errors = new Exception[0];
global String query;
global Database.QueryLocator start(Database.BatchableContext bc) {
string query = 'SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= \'Employee\' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC ';
return database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<User> scope){
system.debug('Scope size' +scope.size());
try{
String currentUserLink = URL.getSalesforceBaseUrl().toExternalForm() + '/';
if(scope.size() >0){
for(user u: scope){
if(u.IsEmailSendToNonActive__c != true){
u.IsEmailSendToNonActive__c = true;
string[] toAddress = new string[] {u.Email};
string subject = 'Notification Of User Deactivation';
string plainBody = 'TEST'
SendEmail(toAddress,subject, plainBody, null, null );
update u;
}
}
}
}
catch(exception e){
errors.add(e);
}
}
global void finish(Database.BatchableContext bc){
//Admins email addresses
List<string> emailAdd = new List<string>();
for(AdminsEmailList__c emad : AdminsEmailList__c.getAll().values())
{
system.debug('emad.Email__c:'+emad.Email__c);
emailAdd.add(emad.Email__c);
}
List<AggregateResult> numberOfRows = [Select count(id) from user where IsEmailSendToNonActive__c=True and lastmodifieddate = today];
integer numRow = (integer)numberOfRows[0].get('expr0');
AsyncApexJob a = [SELECT Id,Status,JobType,NumberOfErrors,JobItemsProcessed,TotalJobItems,CompletedDate,ExtendedStatus
FROM AsyncApexJob WHERE Id =:BC.getJobId()];
//check for errors if no error then proceed
string errorString;
for(Exception s: errors)
{
errorString = errorString + s.getMessage();
}
if(!errors.isEmpty()) {
string errSub = 'Error(s) occurred during sending emails to Non Active user batch process.';
string errBody = 'below is the error details: \n\n'+errorString;
SendEmail(emailAdd, errSub, errBody, null, null);
}
}
public void SendEmail(List<string> toEmailAdd, string subject, string body, string attchmentName, string attachment){
system.debug('toEmailAdd::'+toEmailAdd);
if(toEmailAdd != null && !toEmailAdd.isEmpty()){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(toEmailAdd);
mail.setSubject(subject);
mail.setSaveAsActivity(false);
mail.setPlainTextBody(body);
Messaging.sendEmail(new Messaging.Email[] { mail });
}
}
}
--- Schedular --
global class ScheduleSendEmailToNonActiveUsers implements Schedulable{
global void execute(SchedulableContext sc){
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s, 10);
}
}
--- TEST CLASS -----
@isTest
public class SendEmailtoNonActiveUsersBatch_Test {
@IsTest(seeAllData=true)
public static void SendEmailTest_positive()
{
User us = [Select id from User where Id = :UserInfo.getUserId()];
System.runAs(us)
{
List<user> uu = [SELECT id,Firstname,Lastname,Profile.name, email,Isactive, LastLoginDate, category__c,IsEmailSendToNonActive__c FROM User where IsActive=True and Category__c= 'Employee' and IsEmailSendToNonActive__c != true and LastLoginDate < LAST_N_DAYS:20 order by Firstname ASC Limit 10];
Test.startTest();
SendEmailtoNonActiveUsersBatch s = new SendEmailtoNonActiveUsersBatch();
database.executeBatch(s);
Test.stopTest();
}
}
}
Another observation: test class should execute DML query menstioned in test class(resulte records 10). But when I run the test class it take query mentioned in batch apex(result records 162).
- Sisodia Saurabh
- June 27, 2019
- Like
- 0
- Continue reading or reply
lightning datatable columns name getting truncated, need to define fix length to columns and horizontal scroll bar
Hi All,
I have created a component to should contact column on account. I have to show records in lightning: datatable with 17 columns. When I increase the number of columns, component truncate the headers and try to fit all the columns in component default width.
Expected output: component should not trim and wrap the header and should all 17 columns with scroll bar.
Below is the screen shot. highlited column is: LEADSOURCE (component wrapped it)
Thanks.
I have created a component to should contact column on account. I have to show records in lightning: datatable with 17 columns. When I increase the number of columns, component truncate the headers and try to fit all the columns in component default width.
Expected output: component should not trim and wrap the header and should all 17 columns with scroll bar.
Below is the screen shot. highlited column is: LEADSOURCE (component wrapped it)
Thanks.
- Sisodia Saurabh
- December 06, 2018
- Like
- 0
- Continue reading or reply
lightning datatable onsort event not firing
Hello Everyone,
I am trying to impelement column sorting. When component loads it sorts the default coulmns value but Lightning: datatable "Onsort" event is not firing, I am getting column names as text only , nothing else(like arrow or something) to click for sorting event firing.
below is my code:
TestAccountComponent
<aura:attribute name="sortedBy" type="String" default="LastName"/>
<aura:attribute name="sortedDirection" type="String" default="asc"/>
<aura:attribute name="defaultSortDirection" type="String"/>
<lightning:datatable minColumnWidth="400px"
data="{! v.Contact }"
columns="{! v.Columns }"
keyField="Id"
hideCheckboxColumn="true"
onsort="{!c.updateColumnSorting}"
sortedBy="{!v.sortedBy}"
sortedDirection="{!v.sortedDirection}"
defaultSortDirection="{! v.defaultSortDirection }"/>
Controller:
getContact : function(component, event, helper) {
debugger;
helper.getStatus(component);
helper.getLeadSourceOpt(component);
component.set("v.Columns", [
{label:"FirstName", fieldName:"FirstName", type:"text"},
{label:"LastName", fieldName:"LastName", type:"text"},
{label:"Phone", fieldName:"Phone", type:"text"},
{label:"Email", fieldName:"Email", type:"text"},
{label:"Contact_Status__c", fieldName:"Contact_Status__c", type:"text"},
{label:"LeadSource", fieldName:"LeadSource", type:"text"}
]);
var rcdID = component.get("v.recordId");
var action = component.get("c.fetchContactList");
action.setParams({
recordId : rcdID
});
action.setCallback(this, function(data) {
var state = data.getState();
if (state === "SUCCESS") {
component.set("v.Contact", data.getReturnValue());
helper.sortData(component, component.get("v.sortedBy"), component.get("v.sortedDirection"));
}
});
$A.enqueueAction(action);
},
updateColumnSorting : function (cmp, event, helper) {
var fieldName = event.getParam('fieldName');
// var sortDirection = event.getParam('sortDirection');
var sortDirection = component.get("v.sortDirection") == 'asc' ? 'desc' : 'asc';
cmp.set("v.sortedBy", fieldName);
cmp.set("v.sortedDirection", sortDirection);
helper.sortData(cmp, fieldName, sortDirection);
}
Helper::
sortData : function (cmp, fieldname, sortDirection) {
debugger;
var data = cmp.get("v.Contact");
var reverse = sortDirection !== 'asc';
data.sort(this.sortBy(fieldname, reverse))
cmp.set("v.Contact", data);
},
sortBy : function (field, reverse, primer) {
var key = primer ?
function(x) {return primer(x[field])} :
function(x) {return x[field]};
reverse = !reverse ? 1 : -1;
return function (a, b) {
return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
}
}
Apex class::
@AuraEnabled
public static List<contact> fetchContactList(Id recordId)
{
system.debug('fetchContactList');
return [Select id, FirstName, LastName, Phone, Email, Contact_Status__c, LeadSource from Contact where AccountId=:recordId];
}
Thanks.
Saurabh Sisodia
I am trying to impelement column sorting. When component loads it sorts the default coulmns value but Lightning: datatable "Onsort" event is not firing, I am getting column names as text only , nothing else(like arrow or something) to click for sorting event firing.
below is my code:
TestAccountComponent
<aura:attribute name="sortedBy" type="String" default="LastName"/>
<aura:attribute name="sortedDirection" type="String" default="asc"/>
<aura:attribute name="defaultSortDirection" type="String"/>
<lightning:datatable minColumnWidth="400px"
data="{! v.Contact }"
columns="{! v.Columns }"
keyField="Id"
hideCheckboxColumn="true"
onsort="{!c.updateColumnSorting}"
sortedBy="{!v.sortedBy}"
sortedDirection="{!v.sortedDirection}"
defaultSortDirection="{! v.defaultSortDirection }"/>
Controller:
getContact : function(component, event, helper) {
debugger;
helper.getStatus(component);
helper.getLeadSourceOpt(component);
component.set("v.Columns", [
{label:"FirstName", fieldName:"FirstName", type:"text"},
{label:"LastName", fieldName:"LastName", type:"text"},
{label:"Phone", fieldName:"Phone", type:"text"},
{label:"Email", fieldName:"Email", type:"text"},
{label:"Contact_Status__c", fieldName:"Contact_Status__c", type:"text"},
{label:"LeadSource", fieldName:"LeadSource", type:"text"}
]);
var rcdID = component.get("v.recordId");
var action = component.get("c.fetchContactList");
action.setParams({
recordId : rcdID
});
action.setCallback(this, function(data) {
var state = data.getState();
if (state === "SUCCESS") {
component.set("v.Contact", data.getReturnValue());
helper.sortData(component, component.get("v.sortedBy"), component.get("v.sortedDirection"));
}
});
$A.enqueueAction(action);
},
updateColumnSorting : function (cmp, event, helper) {
var fieldName = event.getParam('fieldName');
// var sortDirection = event.getParam('sortDirection');
var sortDirection = component.get("v.sortDirection") == 'asc' ? 'desc' : 'asc';
cmp.set("v.sortedBy", fieldName);
cmp.set("v.sortedDirection", sortDirection);
helper.sortData(cmp, fieldName, sortDirection);
}
Helper::
sortData : function (cmp, fieldname, sortDirection) {
debugger;
var data = cmp.get("v.Contact");
var reverse = sortDirection !== 'asc';
data.sort(this.sortBy(fieldname, reverse))
cmp.set("v.Contact", data);
},
sortBy : function (field, reverse, primer) {
var key = primer ?
function(x) {return primer(x[field])} :
function(x) {return x[field]};
reverse = !reverse ? 1 : -1;
return function (a, b) {
return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
}
}
Apex class::
@AuraEnabled
public static List<contact> fetchContactList(Id recordId)
{
system.debug('fetchContactList');
return [Select id, FirstName, LastName, Phone, Email, Contact_Status__c, LeadSource from Contact where AccountId=:recordId];
}
Thanks.
Saurabh Sisodia
- Sisodia Saurabh
- December 05, 2018
- Like
- 0
- Continue reading or reply
Lightning dataTable sortedDirection not working
I'm using lightning dataTable component. But the sortedDirection only ever sorts one direction. The sortDirection param never updates properly. Here is some code:
<aura:component implements="flexipage:availableForAllPageTypes" controller="CrossSellActivityController" access="global"> <!-- Attributes --> <aura:attribute name="activities" type="Array" /> <aura:attribute type="String" name="sortedDirection" default="asc" /> <aura:attribute name="columns" type="List" /> <!-- Component DOM --> <div> <lightning:datatable keyField="id" data="{!v.activities}" columns="{!v.columns}" sortedDirection="{!v.sortedDirection}" onsort="{!c.updateColumnSorting}" hideCheckboxColumn="true" /> </div> </aura:component>Here is the column definition:
var columns = [ { label: 'Program Key', fieldName: 'Program_Key__c', type: 'text', sortable: true }, { label: 'Status', fieldName: 'Disposition__c', type: 'text', sortable: true }, { label: 'User', fieldName: 'Username', type: 'text', sortable: true }, { label: 'Asset', fieldName: 'Asset', type: 'text', sortable: true }, { label: 'Timestamp', fieldName: 'CreatedDate', type: 'date', typeAttributes: { day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true }, sortable: true } ]; component.set("v.columns", columns);And where I console.log out the sortedDirection variable:
updateColumnSorting : function(component, event, helper) { var sortDirection = event.getParam('sortDirection'); component.set("v.sortedDirection", sortDirection); console.log('sortDirection: ', sortDirection); },The console.log always outputs 'asc' never flips to 'desc'. I've even tried changing the definition to Boolean with no luck.
<aura:attribute type="Boolean" name="sortedDirection" default="false" />I've also tried flipping it myself with a truthy check and setting it back on the sortedDirection attribute, but that doesn't work either. Am I doing something wrong?
- Matt Brown 71
- November 02, 2018
- Like
- 0
- Continue reading or reply
passing parameter to URL in lightning component
Hi,
It was really simple to open URL in new window with passing parameters and some Validations using salesforce classic Onclick Java. for example:
if({!ISBLANK( Account.CSOne_Case_Number__c )})
{
window.open('https://.na29.visual.force.com/apex/Relationship360?rId={!Account.Gainsight_Relationship_ID__c}');
}
Now we are moving to Salesforce Lightning and As Onclick Javascript is not supported. can someone please let me know how can I achieve this in Lightning.
Thanks in advance.
Saurabh Sisodia
It was really simple to open URL in new window with passing parameters and some Validations using salesforce classic Onclick Java. for example:
if({!ISBLANK( Account.CSOne_Case_Number__c )})
{
window.open('https://.na29.visual.force.com/apex/Relationship360?rId={!Account.Gainsight_Relationship_ID__c}');
}
Now we are moving to Salesforce Lightning and As Onclick Javascript is not supported. can someone please let me know how can I achieve this in Lightning.
Thanks in advance.
Saurabh Sisodia
- Sisodia Saurabh
- January 11, 2018
- Like
- 0
- Continue reading or reply
Future method cannot be called from a future or batch method: Error
Hi,
I am getting this error while I am trying to update contact which are associated to user objects.
trigger CommunityLoginOnContactTrigger on User (after update) {
for(User u: trigger.new)
{
system.debug('USer trigger got triggered');
if(system.isFuture()) return;
if(u.ContactId != null)
{
if(u.LastLoginDate__c != null)
{
UpdateContactFromTestUser.updateContacts(u.ContactId, u.LastLoginDate__c);
}
}
}
}
global class UpdateContactFromTestUser {
@future
public static void updateContacts(String userId, Datetime Lastlogin) {
if (userId!=null && userId != '') {
Contact c = [ Select Last_Community_Login__c,Community_Category__c from Contact where id =:userId];
if(c.Last_Community_Login__c != Lastlogin)
{
c.Last_Community_Login__c = Lastlogin;
update c;
}
}
}
}
I am getting this error while I am trying to update contact which are associated to user objects.
trigger CommunityLoginOnContactTrigger on User (after update) {
for(User u: trigger.new)
{
system.debug('USer trigger got triggered');
if(system.isFuture()) return;
if(u.ContactId != null)
{
if(u.LastLoginDate__c != null)
{
UpdateContactFromTestUser.updateContacts(u.ContactId, u.LastLoginDate__c);
}
}
}
}
global class UpdateContactFromTestUser {
@future
public static void updateContacts(String userId, Datetime Lastlogin) {
if (userId!=null && userId != '') {
Contact c = [ Select Last_Community_Login__c,Community_Category__c from Contact where id =:userId];
if(c.Last_Community_Login__c != Lastlogin)
{
c.Last_Community_Login__c = Lastlogin;
update c;
}
}
}
}
- Sisodia Saurabh
- September 01, 2017
- Like
- 0
- Continue reading or reply
Need solution to open VF page in new tab
Hi All,
I want to implement a functionality in which when user click on Item it should display information in new Tab instead of new page.
My scenario description:
Name First Name Last Name Phone NoStart Date DOB Prog Lang
Emp-0034 Runthistime
<apex:column headerValue="Name" >
<apex:outputLink value="/apex/Emp_DisplayForm?id={!a.id}"> {!a.name}</apex:outputLink>
</apex:column>
On click of Emp-0034. it opens item in my custom Emp_DisplayForm as new page. But I want it to be open in new tab?
Thanks.
Srb
I want to implement a functionality in which when user click on Item it should display information in new Tab instead of new page.
My scenario description:
Name First Name Last Name Phone NoStart Date DOB Prog Lang
Emp-0034 Runthistime
<apex:column headerValue="Name" >
<apex:outputLink value="/apex/Emp_DisplayForm?id={!a.id}"> {!a.name}</apex:outputLink>
</apex:column>
On click of Emp-0034. it opens item in my custom Emp_DisplayForm as new page. But I want it to be open in new tab?
Thanks.
Srb
- Sisodia Saurabh
- June 03, 2016
- Like
- 0
- Continue reading or reply
Ready to Volunteer in Salesforce.com for Non profit Organizations
I have my Salesforce.com Certified Administrator credential, and would like to gain more experience in the field.
I would like to volunteer my time (20 hours a week) to help a non-profit with any Salesforce.com admin tasks.
I am located in the Fremont California (USA) region, but naturally, can work remotely with any English-language org.
Appreciate any leads or any direction you can give.
Sincerely,
Sunny Singh
510-449-5752
I would like to volunteer my time (20 hours a week) to help a non-profit with any Salesforce.com admin tasks.
I am located in the Fremont California (USA) region, but naturally, can work remotely with any English-language org.
Appreciate any leads or any direction you can give.
Sincerely,
Sunny Singh
510-449-5752
- Sunny Singh 39
- October 07, 2015
- Like
- 0
- Continue reading or reply