Tuesday, June 26, 2018

Asynchronous Apex: Using Queueable Apex


Queueable jobs are similar to future methods, but they provide you with these additional benefits.
  • Getting an ID for your job: When you submit your job by invoking the System.enqueueJob method, the method returns the ID of the new job. This ID corresponds to the ID of the AsyncApexJob record. You can use this ID to identify your job and monitor its progress.
  • Using non-primitive types: Your queueable class can contain member variables of non-primitive data types, such as sObjects or custom Apex types.
  • Chaining jobs: You can chain one job to another job by starting a second job from a running job. Chaining jobs is useful if you need to do some processing that depends on another process to have run first.
public class AsyncExecutionExample implements Queueable {
    public void execute(QueueableContext context) {
        Account a = new Account(Name='Acme',Phone='(415) 555-1212');
        insert a;        
    }
}

To add this class as a job on the queue, call this method:
ID jobID = System.enqueueJob(new AsyncExecutionExample());

Chaining Jobs

To chain a job to another job, submit the second job from the execute() method of your queueable class. You can add only one job from an executing job, which means that only one child job can exist for each parent job. You can refer the code below for chaining jobs:

...
...
...
for (Case caseRecord : cases)
 caseRecord.Status = 'Closed';

for (Lead lead : leads)
 lead.Status = 'Inactive';

Map<Integer, List<sObject>> indexToObjects = new Map<Integer, List<SObject>>();
indexToObjects.put(0, cases);
indexToObjects.put(1, leads);

Integer startingIndex = 0;
System.enqueueJob(new Worker(indexToObjects, startingIndex));

Worker.cls
public without sharing class Worker implements Queueable {
 Map<Integer, List<sObject>> indexToObjectUpdates;
 Integer index;

 public Worker(Map<Integer, List<sObject>> indexToObjectUpdates, Integer index) {
  this.indexToObjectUpdates = indexToObjectUpdates;
  this.index = index;
 }

 public void execute(QueueableContext context) {
  if (!indexToObjectUpdates.containsKey(index))
   return;

  update indexToObjectUpdates.get(index);

  Integer nextIndex = index + 1;
  if (indexToObjectUpdates.containsKey(nextIndex))
   System.enqueueJob(new Worker(indexToObjectUpdates, nextIndex));
 }
}

Points to remember:
  • Apex allows HTTP and web service callouts from queueable and chained queueable jobs, if they implement the Database.AllowsCallouts marker interface.
  • You can monitor the status of your job programmatically by querying AsyncApexJob or through the user interface in Setup by entering Apex Jobs in the Quick Find box, then selecting Apex Jobs.
Share This:    Facebook Twitter

Sunday, May 13, 2018

A simple Node.js web application


const express = require("express");
const app = express();

const Joi = require("joi");

app.use(express.json());

const genres = [
  { id: 1, name: "Action" },
  { id: 2, name: "Horror" },
  { id: 3, name: "Romance" }
];

app.get("/api/genres", (req, res) => {
  res.send(genres);
});

app.get("/api/genres/:id", (req, res) => {
  const genre = genres.find(c => c.id === parseInt(req.params.id));
  if (!genre)
    return res.status(404).send("The genre with the given ID was not found.");
  res.send(genre);
});

app.post("/api/genres", (req, res) => {
  const { error } = validateGenre(req.body);
  if (error) return res.status(400).send(error.details[0].message);

  const genre = {
    id: genres.length + 1,
    name: req.body.name
  };
  genres.push(genre);
  res.send(genre);
});

app.put("/api/genres/:id", (req, res) => {
  const genre = genres.find(c => c.id === parseInt(req.params.id));
  if (!genre)
    return res.status(404).send("The genre with the given ID was not found.");

  const { error } = validateGenre(req.body);
  if (error) return res.status(400).send(error.details[0].message);

  genre.name = req.body.name;
  res.send(genre);
});

app.delete("/api/genres/:id", (req, res) => {
  const genre = genres.find(c => c.id === parseInt(req.params.id));
  if (!genre)
    return res.status(404).send("The genre with the given ID was not found.");

  const index = genres.indexOf(genre);
  genres.splice(index, 1);

  res.send(genre);
});

function validateGenre(genre) {
  const schema = {
    name: Joi.string()
      .min(3)
      .required()
  };

  return Joi.validate(genre, schema);
}

const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}...`));

Share This:    Facebook Twitter

Monday, April 16, 2018

Salesforce Lightning: How to deal with cookies



You can use the below helper method to create a cookie.


So as an example, to create a cookie that stores the name of a visitor, you can call the helper method like below:
helper.createCookie('username', 'John Doe', 7);

To create a session cookie, don't pass any value for days. So you will be calling the helper method like below:
helper.createCookie('username', 'John Doe');

After executing the code above, the name of the cookie generated is LSKey[c]username. The name of the cookie is prefixed with LSKey[<c>] where c is the namespace. So to retrieve the value of this cookie, use the below code:


So as an example, to retrieve the cookie value, you can call the helper method like below:
helper.getCookie('username');

Check the link in the references section to check how to delete the cookie.

References: https://www.sitepoint.com/how-to-deal-with-cookies-in-javascript/
Share This:    Facebook Twitter

Saturday, April 14, 2018

Testing the performance of Salesforce Lightning components


Unlike regular timestamps created with Date.now(), a high resolution timestamp is precise to a thousandth of a millisecond. Having this level of precision can be very useful when testing code that needs to run really fast. For those that work in environments that demand lightning fast code execution, this new level of accuracy is incredibly useful. To generate a high resolution timestamp, you need to use the now method that is available on the performance object.

Please note that while Date.now() returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC, performance.now() returns the number of milliseconds, with microseconds in the fractional part, from performance.timing.navigationStart(), the start of navigation of the document, to the performance.now() call.

How to use performance.now() ?
You need to create a variable before and after the piece of code you wish to test, and populate those variables with the value returned by performance.now(). Subtracting the first variable from the second variable will then give you the amount of time that your code took to execute.

The code below shows a simple example of how to do this. I am calling a server-side controller action from a client-side controller of a Lightning component. Before adding the server-side controller action to the queue of actions to be executed, I have declared startTime variable, populating with the value returned by performance.now(). After the server-side action is completed, I am checking the amount of time the code took to execute.
callServer: function (component, method, params, helper, callback) {

    var action = component.get(method);
    if (params) {
        action.setParams(params);
    }

    action.setCallback(this, function (response) {
     console.log('Time taken:', (performance.now() - startTime));
        var state = response.getState();
        if (state === "SUCCESS") {
            callback.call(this, response.getReturnValue());
        } else if (state === "ERROR") {
         console.log(response.getError());
        }
    });
    var startTime = performance.now();
    $A.enqueueAction(action);

}


Share This:    Facebook Twitter

Total Pageviews

My Social Profiles

View Sonal's profile on LinkedIn

Tags

__proto__ $Browser Access Grants Accessor properties Admin Ajax AllowsCallouts Apex Apex Map Apex Sharing AssignmentRuleHeader AsyncApexJob Asynchronous Auth Provider AWS Callbacks Connected app constructor Cookie CPU Time CSP Trusted Sites CSS Custom settings CustomLabels Data properties Database.Batchable Database.BatchableContext Database.query Describe Result Destructuring Dynamic Apex Dynamic SOQL Einstein Analytics enqueueJob Enterprise Territory Management Enumeration escapeSingleQuotes featured Flows geolocation getGlobalDescribe getOrgDefaults() getPicklistValues getRecordTypeId() getRecordTypeInfosByName() getURLParameters Google Maps Governor Limits hasOwnProperty() Heap Heap Size IIFE Immediately Invoked Function Expression Interview questions isCustom() Javascript Javascript Array jsForce Lightning Lightning Components Lightning Events lightning-record-edit-form lightning:combobox lightning:icon lightning:input lightning:select LockerService Lookup LWC Manual Sharing Map Modal Module Pattern Named Credentials NodeJS OAuth Object.freeze() Object.keys() Object.preventExtensions() Object.seal() Organization Wide Defaults Override PDF Reader Performance performance.now() Permission Sets Picklist Platform events Popup Postman Primitive Types Profiles Promise propertyIsEnumerable() prototype Query Selectivity Queueable Record types Reference Types Regex Regular Expressions Relationships Rest API Rest Operator Revealing Module Pattern Role Hierarchy Salesforce Salesforce Security Schema.DescribeFieldResult Schema.DescribeSObjectResult Schema.PicklistEntry Schema.SObjectField Schema.SObjectType Security Service Components Shadow DOM Sharing Sharing Rules Singleton Slots SOAP API SOAP Web Services SOQL SOQL injection Spread Operator Star Rating stripInaccessible svg svgIcon Synchronous this Token Triggers uiObjectInfoApi Upload Files VSCode Web Services XHR
Scroll To Top