Motivation behind this
This is my first experience on delivering webinar with Salesforce and during this course of preparation I have learnt a lot from Salesforce Team. Thanks to all of them.
To explore Lightning Web Components Open Source (LWC OSS) components that's need to be deployed in Heroku there are steps to be followed which has been delivered during our webinar.
Sharing those steps which will help developers to extend this functionality.
Recording of CodeLive session
Pre-requisites
Step by Step process and related references
a) Create first LWC Open source App
npx create-lwc-app my-app cd my-app npm run watch
App will be visible running at Local Server (https://localhost:3001)
b) Steps to deploy LWC OSS App at Heroku
Create a Procfile with web: npm run serve and place the file under root folder.
Run the following command
heroku login
git add .
git commit -m "Intial Commit"
git push heroku master
heroku open
Optionally, we could also run git remote -v to see the remote URLs get created.
Navigate to *.herokuapp.com and see the output.
Presentation Video at 22:15
c) Setting up Heroku Postgres database
- Navigate to Heroku Dashboard, and click on App
- Go to Resources
- In the Add ons section, search for Heroku PostGres, and click Provision
- Navigate to Settings and see Config Vars. See that Database URL got added
d) Setting up Heroku Connect
Refer Set Up Heroku Connect Trailhead Module
After that, from the Heroku Dashboard:
- Go to settings and expand database credentials
- Copy Database URI value, and Heroku CLI value
e) Locally query for remote data from Postgres
We can run Heroku CLI to see the remote data.
Presentation Video at 46:13
Run following command
heroku pg:psql postgresql-cubic-28239 --app warm-ravine-31983
And execute your query like:
SELECT * FROM salesforce.product__c
Unlike SOQL, it supports (*) to retrieve all field values.
Output:
f) Update App to connect to Postgres
Run following command to install dependency
npm install pg
- Add following code to retrieve records from data and preparing JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | const { Client } = require('pg'); module.exports = app => { // put your express app logic here app.get('/data/products', (req, res) => { var products = []; const client = new Client({ connectionString: process.env.DATABASE_URL, ssl: true }); client.connect(); client.query( 'SELECT sfid,name,picture_url__c,price__c FROM salesforce.product__c;', (err, data) => { if (err) console.log(err); products = data.rows.map(productRecord => { return { id: productRecord.sfid, name: productRecord.name, price: '$' *+* productRecord.price__c, quantity: 0, picture: productRecord.picture_url__c }; }); res.json(products); client.end(); } ); }); }; |
- Create entry in .env file (placing under root directory) for DATABASE_URL
npm install dotenv
- Make necessary changes on Client side .js file to display data.
Running locally it will display following output
Presentation Video 56:22
g) Setting up connection with Salesforce
JSForce (f.k.a. Node Salesforce) is a isomorphic JavaScript Library utilizing Salesforce's API: It works both in browser and with Node.js.
It encapsulates the access to various APIs provided by Salesforce in asynchronous JavaScript function calls.
Run following command to install dependency
npm install jsforce
And use following code to establish connection inside /server/index.js file
Define SF_USERNAME and SF_PASSWORD in .env file.
const jsforce = require('jsforce'); const { SF_USERNAME, SF_PASSWORD } = process.env; if (!(SF_USERNAME && SF_PASSWORD)) { console.error( 'Cannot start app: missing mandatory configuration. Check your .env file.' ); process.exit(-1); } const conn = new jsforce.Connection({ loginUrl: 'https://login.salesforce.com' }); conn.login(SF_USERNAME, SF_PASSWORD, err => { if (err) { console.error(err); process.exit(-1); } });
Refer documentation: JSForce Connection
h) Insert data using webservice callout
In the demo, we have also installed body-parser.
Node.js body parsing middleware which parses incoming request bodies in a middleware before your handlers, available under the
req.body
property.npm install body-parser
In the /server/index.js file use following code to make callout.
module.exports = app => { app.use(express.json()); app.post('/data/placeOrder', (req, res) => { conn.apex.post('/placeOrder/', req.body, (err, data) => { if (err) { console.error(err); } res.json(data); }); }); };
This will get called from front-end /client/productList.html.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | handleClick() { let emailaddress = this.template.querySelector('.emailaddress').value; let obj = { email: emailaddress, productList: JSON.stringify(this.allProducts) }; if (emailaddress.length === 0) { // eslint-disable-next-line no-alert alert('Please enter email address'); } else { fetch('data/placeOrder', { method: 'POST', // or 'PUT' body: JSON.stringify(obj), // data can be `string` or {object}! headers: { 'Content-Type': 'application/json' } }) .then(response => { return response.json(); }) .then(data => { // eslint-disable-next-line no-alert alert(data); }); } } |
Refer Documentation: Fetch API
i) Setting up external GIT environment
In the Heroku dashboard:
- Go to deploy tab of the app
- Connect to GitHub
- Select Repo, Enable Auto Deploys
Run following command to add origin and verifying
git remote add origin https://github.com/<yourrepo>/XXXXX.git
git remote -v
Presentation Video 1:15:45
j) Setting up Pipeline
A pipeline is a group of Heroku apps that share the same codebase. Each app in a pipeline represents one of the following stages in a continuous delivery workflow:
- Development
- Review
- Staging
- Production