LWC Open Source – Connection to Salesforce
So we created our skeleton app as previous article explains.
Now lets connect it to Salesforce Org.
For this we will use a great and easy open source framework JSForce
npm i jsforce
And while we are on it let’s install also – dotenv will help us store some login credentials details
npm i dotenv
We can simply use our User credentials to login to Salesforce and get Data.
Create a .env
file and setup the following credentials inside
SF_LOGIN_URL=https://CS81.salesforce.com [email protected] SF_PASSWORD=XXXXX SF_TOKEN=uxxxxxxxxxxxxxxxx
Create the connection
- inside your server folder create a new file
salesforce-connection.js
// Simple Express server setup to serve for local testing/dev API server /* eslint-disable no-undef */ const express = require('express'); const compression = require('compression'); const helmet = require('helmet'); const path = require('path'); const jsforce = require('jsforce'); require('dotenv').config(); const { SF_USERNAME, SF_PASSWORD, SF_TOKEN, SF_LOGIN_URL } = process.env; if (!(SF_USERNAME && SF_PASSWORD && SF_TOKEN && SF_LOGIN_URL)) { console.error( 'Cannot start app: missing mandatory configuration. Check your .env file.' ); process.exit(-1); } const conn = new jsforce.Connection({ loginUrl: SF_LOGIN_URL }); conn.login(SF_USERNAME, SF_PASSWORD + SF_TOKEN, (err) => { if (err) { console.error(err); process.exit(-1); } }); const app = express(); app.use(helmet()); app.use(compression()); const HOST = process.env.HOST || 'localhost'; const PORT = process.env.PORT || 3001; const DIST_DIR = './dist'; const Account_API = '/api/v1/accounts'; app.get(Account_API, (req, res) => { // change the query to your needs const soql = `SELECT Id, Name, Type FROM Account LIMIT 100`; conn.query(soql, (err, result) => { if (err) { res.sendStatus(500); } else if (result.records.length === 0) { res.status(404).send('no records were found.'); } else { // const outputRecords = result.records.map( // (item) => item.Name // ); res.send({ data: result.records }); } }); }); app.use(express.static(DIST_DIR)); app.use('*', (req, res) => { res.sendFile(path.resolve(DIST_DIR, 'index.html')); }); app.listen(PORT, () => console.log(`✅ Server started on: http://${HOST}:${PORT}${Account_API}`); );
This should handle the login and will perform a query to get data from your org.
Nodemon track our server changes soo we can simply add the path to the configuration inside the package.json
.
"nodemonConfig": { "watch": [ "src/server/**/*.js" ], "ext": "js", "ignore": [ "src/**/*.spec.js", "src/**/*.test.js" ], "exec": "node ./src/server/salesforce-connection.js" },
Make sure you have the following script inside:
"scripts": { "watch:client": "lwc-services watch", "watch:server": "nodemon", "watch:all": "run-p watch:client watch:server" }
Now when we run npm run watch:serve
and going into the path http://localhost:3001/api/v1/accounts
we can see our response from Salesforce.
We just created an API endpoint that can serve us the data from our org, now we just need to call this endpoint from our client app.
In order to do that let’s create another script file that we can import from our component.
- create a
data
folder inside our main app component - create a new file
apiService.js
- add and export the following function
getRecords
as follows:
const endpointPath = '/api/v1/accounts'; let records = []; export const getRecords = () => fetch(endpointPath) .then((response) => { // console.log(response); if (!response.ok) { throw new Error('No response from server'); } return response.json(); }) .then((result) => { if(result.data) records = result.data; return records; }).catch(error =>{ console.error('calling Salesforce has failed : ', error); });
This will fetch the data from our org using an http callout.
Now we can simply import this service function into our component and call it when we wish.
import { LightningElement, api } from 'lwc'; // adds the service to component import { getRecords } from './data/apiService'; export default class App extends LightningElement { results = ''; connectedCallback() { // fetch data getRecords() .then((reponse) => { this.results = JSON.stringify(reponse); }); } }
We managed to get our data to display on the component.