You need to sign in to do that
Don't have an account?
Kishan Kumar 77
Even after making changes to my code i am getting the same error. I need help with the onrowaction event handler and http callout. I am not sure where i am making mistake. Please help.
---------------------js file-----------------------------
import { LightningElement, track } from 'lwc';
import getOppList from '@salesforce/apex/customSearchController.getOppList';
import {ShowToastEvent} from 'lightning/platformShowToastEvent'
export default class CustomSearch extends LightningElement {
@track opportunity;
sVal='';
receivedMessage;
@track record = [];
@track columns=[
{label: 'Name', fieldName: 'Name',type: 'url',
typeAttributes: {
label: {
fieldName: 'Name'
}
},
sortable: true },
{label: 'Account Name', fieldName: 'AccountId',type: 'url',
typeAttributes: {
label: {
fieldName: 'AccountId.Name'
}
},
sortable: true},
{label: 'Stage Name', fieldName: 'StageName',type: 'picklist'},
{label: 'Type', fieldName: 'Type',type: 'picklist'},
{label: 'Amount', fieldName: 'Amount',type: 'currency'},
{label:'Action',type:'button',typeAttributes: {
label: 'Send Opp',
name: 'Send',
disabled: false,
value: 'send',
iconPosition: 'left'
}
}
];
// 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 !== '') {
getOppList({
searchKey: this.sVal
})
.then(result => {
// set @track opportunities variable with return contact list from server
this.opportunity = 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.opportunity = null;
});
} else {
// fire toast event if input field is blank
const event = new ShowToastEvent({
variant: 'error',
message: 'Search text missing..',
});
this.dispatchEvent(event);
}
}
handleRowAction(event){
const row = event.detail.row;
let actionName = event.detail.action.name;
switch(actionName) {
case 'Send':
this.record = row;
const calloutURI = 'https://herokuapp.com';
fetch(calloutURI, {
method: "POST",
headers: {
"Accept": "application/json"
},
body: JSON.stringify(record)
})
.then((response) => {
return response.json();
})
.then(responseJSON => {
console.log(responseJSON);
console.log(record);
})
.catch(error => {
const event = new ShowToastEvent({
title: 'Error',
variant: 'error',
message: error.body.message,
});
this.dispatchEvent(event);
});
}
}
}
-------------------html file---------------------------
<template>
<div class="slds-m-around_medium">
<div class="slds-m-bottom_small">
<lightning-input type="text"
value={sVal}
label="Search Opportunity"
onchange={updateSeachKey}
></lightning-input>
</div>
<lightning-button label="Search"
onclick={handleSearch}
variant="brand"></lightning-button>
<lightning-datatable data={opportunity} columns={columns} key-field="id" onrowaction={handleRowAction}>
</lightning-datatable>
</div>
</template>
import { LightningElement, track } from 'lwc';
import getOppList from '@salesforce/apex/customSearchController.getOppList';
import {ShowToastEvent} from 'lightning/platformShowToastEvent'
export default class CustomSearch extends LightningElement {
@track opportunity;
sVal='';
receivedMessage;
@track record = [];
@track columns=[
{label: 'Name', fieldName: 'Name',type: 'url',
typeAttributes: {
label: {
fieldName: 'Name'
}
},
sortable: true },
{label: 'Account Name', fieldName: 'AccountId',type: 'url',
typeAttributes: {
label: {
fieldName: 'AccountId.Name'
}
},
sortable: true},
{label: 'Stage Name', fieldName: 'StageName',type: 'picklist'},
{label: 'Type', fieldName: 'Type',type: 'picklist'},
{label: 'Amount', fieldName: 'Amount',type: 'currency'},
{label:'Action',type:'button',typeAttributes: {
label: 'Send Opp',
name: 'Send',
disabled: false,
value: 'send',
iconPosition: 'left'
}
}
];
// 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 !== '') {
getOppList({
searchKey: this.sVal
})
.then(result => {
// set @track opportunities variable with return contact list from server
this.opportunity = 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.opportunity = null;
});
} else {
// fire toast event if input field is blank
const event = new ShowToastEvent({
variant: 'error',
message: 'Search text missing..',
});
this.dispatchEvent(event);
}
}
handleRowAction(event){
const row = event.detail.row;
let actionName = event.detail.action.name;
switch(actionName) {
case 'Send':
this.record = row;
const calloutURI = 'https://herokuapp.com';
fetch(calloutURI, {
method: "POST",
headers: {
"Accept": "application/json"
},
body: JSON.stringify(record)
})
.then((response) => {
return response.json();
})
.then(responseJSON => {
console.log(responseJSON);
console.log(record);
})
.catch(error => {
const event = new ShowToastEvent({
title: 'Error',
variant: 'error',
message: error.body.message,
});
this.dispatchEvent(event);
});
}
}
}
-------------------html file---------------------------
<template>
<div class="slds-m-around_medium">
<div class="slds-m-bottom_small">
<lightning-input type="text"
value={sVal}
label="Search Opportunity"
onchange={updateSeachKey}
></lightning-input>
</div>
<lightning-button label="Search"
onclick={handleSearch}
variant="brand"></lightning-button>
<lightning-datatable data={opportunity} columns={columns} key-field="id" onrowaction={handleRowAction}>
</lightning-datatable>
</div>
</template>
1) record seems an object (not an array)
2) Don't forget this. each time you are using this.record
3) Callout from Lightning web components ( correct )
https://newstechnologystuff.com/2020/06/13/callout-from-lightning-web-components/
https://googlechrome.github.io/samples/fetch-api/fetch-post.html
But look at the console (chrome developer tools) because you need to declare the URL (https://herokuapp.com) as an exception for the CSP ( Content Security Policy ).
https://help.salesforce.com/articleView?id=csp_trusted_sites.htm&type=5 (https://help.salesforce.com/articleView?id=csp_trusted_sites.htm&type=5)
2) AccountId is correct but
AccountId.Nameis incorrect ( Account.Name ? ){label: 'Account Name', fieldName: 'AccountId',type: 'url',
typeAttributes: {
label: {
fieldName:
'AccountId.Name'// Account.Name ? depends on the Apex controller.}
},
sortable: true},
public with sharing class customSearchController {
@AuraEnabled(cacheable=true)
public static list<Opportunity> getOppList(string searchKey){
List<Opportunity> OppList=new List<Opportunity>();
if(searchKey.isNumeric())
{
Decimal searchstringDouble = decimal.valueOf(searchKey);
OppList = [select Id,Name,Account.Name,StageName,Type,Amount,CloseDate
from Opportunity
where Amount=:searchstringDouble];
if(OppList.size() == 0){
throw new AuraHandledException('No Record Found..');
}
}
else{
String newSearchText = searchKey+'%';
OppList =[select Id,Name,Account.Name,StageName,Type,Amount,CloseDate
from Opportunity
where Name like:newSearchText or Account.Name like:newSearchText
or StageName like:newSearchText or Type like:newSearchText];
if(OppList.size() == 0){
throw new AuraHandledException('No Record Found..');
}
}
return OppList;
}
}
I have somehow managed to remove the error that I mentioned above. Now I have two problems :
1. I cannot display the Account name of the opportunity. It displays a URL instead of the name.
2. The above error comes when I click on the Send button to make an HTTP callout.
const calloutURI = "https://herokuapp.com"; (??)
I thought that was not your real URL (hidden) because that should be : const calloutURI = 'https://foo.herokuapp.com/myaction';
https://trailhead.salesforce.com/fr/content/learn/modules/salesforce_heroku_integration/callouts_workflow_with_heroku
The call via an Apex class is more sure.
Heroku from Apex (sure for Heroku, better option for a quick result):
https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services/apex_integration_rest_callouts
Fetch = GET (example) : A service component is an LWC - that should also work (but CORS error with Heroku).
https://developer.salesforce.com/blogs/2019/05/lightning-web-components-service-components.html
I tried a very simple Heroku call like you with a simple GET and I got the same CORS error each time (even if Setup > CORS (changed) ).
The REST Heroku call via an Apex class is sure but it is interesting to verify if a call from the front end (client) is also possible.
The documentaiton says that API call is not possible from the front end but the fetch above is also a service.
Heroku is CORS compatible by default ( I did'nt find a choice to change on the Heroku side).