Friday, November 1, 2019

Supplementary - Extend Salesforce Implementation with Heroku Webinar

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 


Followings are the pre-requisites:



Step by Step process and related references


a) Create first LWC Open source App


 Refer lwc.dev and run the following CLI steps


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




  1. Navigate to Heroku Dashboard, and click on App
  2. Go to Resources
  3. In the Add ons section, search for Heroku PostGres, and click Provision
  4. Navigate to Settings and see Config Vars. See that Database URL got added
Presentation Video at 36:01

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.
Refer Documentation: Connecting in Node.js

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


Refer Documentation: pipelines


k) Scaling







Further References: