Friday, September 8, 2017

Salesforce Lightning: Lookup Component


I created a simple lookup component in Lightning. Its fully based on Lightning Design Systems. You can check the Github link in the reference section. During initialization, the component query for the list of strings (using apex code) to be displayed and store in an attribute. So when the user enters a search keyword, the request won't go to Salesforce again and will query the Javascript string array for the filtered results.

How to use?

From your Lightning component, add a lookup component using the following markup:
<c:DemoLookup placeholder="Enter partner Name" actionMethod="c.getAccountOptions"/>

You need to pass a list of strings which will get displayed in the lookup options when the user enters an input. A sample method is as below:
@AuraEnabled
public static List<String> getAccountOptions() {
    List<String> options = new List<String>();
    for (Account a : [
            SELECT Name
            FROM Account
            LIMIT 100
    ]) {
        options.add(a.Name);
    }
    return options;
}

Reference:
https://github.com/iamsonal/DemoLookup
Share This:    Facebook Twitter

Saturday, September 2, 2017

Lightning: Fetch current location details using Google Maps API

Using Google Maps, I was trying to fetch the current city and other details in a Lightning component using Javascript, but I was getting some error in browser console. I believe that is because of Locker service as described in the reference link. So I had to take a different approach.

But first, we need the latitude and longitude of the user who is accessing the Lightning page. The HTML Geolocation API is used to get the geographical position of a user. Since this can compromise privacy, the position is not available unless the user approves it. The getCurrentPosition() method is used to return the user's position. The example below returns the latitude and longitude of the user's position.

checkGeoLocation : function(component, event, helper) {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            var lat = position.coords.latitude;
            var lon = position.coords.longitude;
            var action = component.get("c.getCityName");
            action.setParams({
                "latitude": lat,
                "longitude": lon
            });
            action.setCallback(this, function(response) {
                var state = response.getState();
                if (state === "SUCCESS") {
                    var location = response.getReturnValue();
                }
            });
            $A.enqueueAction(action);
        });
    } else {
        console.log('Your browser does not support GeoLocation');
    }
}

To fetch the city details, we need to invoke the Google maps API. We need to send the location details as parameters. The results element in the response needs to be parsed in Apex to extract the desired values. In my case, JsonReader class did the work for me.

Please go through the documentation of Google maps, the link of which has been provided in the reference section. The following fields of the results element are of significance:
1. address_components[]
2. types[]

@AuraEnabled
public static String getCityName (Decimal latitude, Decimal longitude) {
    String url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=' + latitude + ',' + longitude + '&sensor=true';
    JsonReader jsonobj = new JsonReader(getHttp(url));
    String status = jsonObj.getString('status');
    System.debug(status);
    
    JsonReader addressComponentObj = null;
    String locality= null;
    String adminAreaLevel2= null;
    List<Object> types = null;
    
    for(Object obj : jsonObj.getList('results[0].address_components')) {
        addressComponentObj = new JsonReader(obj);
        types = addressComponentObj.getList('types');
        for(Object typeObj : types) {
            String type = (String) typeObj;
            if (type.equalsIgnoreCase('locality')) {
                locality = addressComponentObj.getString('long_name');
            }
            if (type.equalsIgnoreCase('administrative_area_level_2')) {
                adminAreaLevel2 = addressComponentObj.getString('short_name');
            }
        }
    }
    return (locality + ', ' + adminAreaLevel2);
}

And that's it.


Reference: http://www.rattanpal.com/2017/03/19/salesforce-implement-google-maps-lightning-components/
https://developers.google.com/maps/documentation/geocoding/intro
Share This:    Facebook Twitter

Saturday, August 26, 2017

Salesforce Lightning Interview Questions I


1. What are the different types of Lightning events?
  • Browser: browser notifications that are triggered by user interaction with an element. Eg. onClick
  • System: fired by LC framework during LC lifecycle. They notify component states. Eg. init, render, afterRender
  • Navigation: force:navigateToURL, force:createRecord, force:editRecord
  • Component: A component event is fired from an instance of a component. A component event can be handled by the component that fired the event or by a component in the containment hierarchy that receives the event.
  • Application: Application events follow a traditional publish-subscribe model. An application event is fired from an instance of a component. All components that provide a handler for the event are notified.


2. How to register, fire and handle a component and application event?
<aura:registerEvent name="componentEventFired" type="c:compEvent"/>
<aura:registerEvent name="appEvent" type="c:appEvent"/>

var compEvents = cmp.getEvent("componentEventFired");
compEvents.setParams({ "context" : parentName });
compEvents.fire();

var appEvent = $A.get("e.c:appEvent");
appEvent.setParams({ "context" : parentName });
appEvent.fire();
...
...
...
...
...
<aura:handler event="c:appEvent" action="{!c.handleApplicationEventFired}"/>
<aura:handler name="componentEventFired" event="c:compEvent" 
 action="{!c.handleComponentEventFired}"/>

{
 handleComponentEventFired : function(cmp, event) {
  var context = event.getParam("context");
 },

 handleApplicationEventFired : function(cmp, event) {
  var context = event.getParam("context");
 }
}
For more details, check the link below:
http://hellosnl.blogspot.in/2017/06/lightning-advanced-events-example.html


3. Let's say that you have an app myApp.app that contains a component myCmp.cmp with a ui:button component. During initialization, the init() event is fired in what order?
Answer: ui:button, ui:myCmp, and myApp.app.


4. Why do we use @AuraEnabled annotation?
  • Use @AuraEnabled on Apex class static methods to make them accessible as remote controller actions in your Lightning components.
  • Use @AuraEnabled on Apex instance methods and properties to make them serializable when an instance of the class is returned as data from a server-side action

5. Why do we use $A.enqueueAction(action)?
It adds the server-side controller action to the queue of actions to be executed. Rather than sending a separate request for each individual action, the framework processes the event chain and batches the actions in the queue into one request. The actions are asynchronous and have callbacks.


6. What is Namespace?
It is used to group related components together.


7. What is LockerService?
It enhances security by isolating Lightning components in their own namespace. A component can only traverse the DOM and access elements created by a component in the same namespace.


8. Examples of how to use some of the out-of-the-box events to enable component interation within your Lightning components?
$A.get("e.force:refreshView").fire(): reloads all data for the view.

createRecord : function (component, event, helper) {
    var createRecordEvent = $A.get("e.force:createRecord");
    createRecordEvent.setParams({
        "entityApiName": "Contact"
    });
    createRecordEvent.fire();
}

editRecord : function(component, event, helper) {
    var editRecordEvent = $A.get("e.force:editRecord");
    editRecordEvent.setParams({
         "recordId": component.get("v.contact.Id")
   });
    editRecordEvent.fire();
}


9. What is Lightning CLI?
It is a Heroku Toolbelt plugin that lets you scan your code for general JavaScript coding issues and lightning-specific issues.


10. Difference between bound and unbound expressions.
Bound expression {!expression}
  • Any change to the value of the childAttr attribute in c:child also affects the parentAttr attribute in c:parent and vice versa.
  • When you use a bound expression, a change in the attribute in the parent or child component triggers the change handler in both components.
Unbound expression {#expression}
  • Any change to the value of the childAttr attribute in c:child doesn’t affect the parentAttr attribute in c:parent and vice versa.
  • When you use an unbound expression, the change is not propagated between components so the change handler is only triggered in the component that contains the changed attribute.
For more details, check this link: http://hellosnl.blogspot.in/2017/05/data-binding-between-components.html


11. Use of THIS CSS class?
This adds namespacing to CSS and helps prevent one component's CSS from blowing away another component's styling.


12. How to set the value of an inherited attribute?
Use the <aura:set> tag.


13. What are the different ways to conditionally display markup, and what is the preferred approach?
Using the <aura:if> tag
Use CSS to toggle visibility of markup by calling $A.util.toggleClass(cmp, 'class') in JavaScript code.


14. What is $Resource global value provider? Is it possible to obtain a reference to a static resource in Javascript code?
It lets you reference images, style sheets, and JavaScript code you’ve uploaded in static resources.
To obtain a reference to a static resource in JavaScript code, use $A.get('$Resource.resourceName').
For more details, check this link http://hellosnl.blogspot.in/2017/04/lightning-using-static-resources.html


15. Let’s say you have several buttons that reuse the same onclick handler. How will you retrieve the name of the button that fired the event?
http://hellosnl.blogspot.in/2017/05/which-button-was-pressed.html


16. What are the names of interfaces that are added to a Lightning component to allow it to be used as custom tabs, and to be used in Lightning and Community builder?
http://hellosnl.blogspot.in/2017/05/configuring-lightning-components.html


17. What is the use of force:hasRecordId interface?
Add the force:hasRecordId interface to a Lightning component to enable the component to be assigned the ID of the current record.
The recordId attribute is set only when you place or invoke the component in a context of a record. For example, when you place the component on a record page, or invoke it as an action from a record page or object home. In all other cases, such as when you create this component programmatically inside another component, recordId isn’t set, and your component shouldn’t depend on it.


18. How to delete a design attribute for a component that implements the flexipage:availableForAllPageTypes or forceCommunity:availableForAllPageTypes interface?
First remove the interface from the component before deleting the design attribute. Then reimplement the interface. If the component is referenced in a Lightning page, you must remove the component from the page before you can change it.


19. How to add Lightning components to your Visualforce pages?
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_visualforce.htm


Share This:    Facebook Twitter

Friday, August 25, 2017

Javascript Accessor Properties

There are two different types of properties: data properties and accessor properties.

  • Data properties contain a value.
  • Accessor properties don’t contain a value but instead define a getter function and a setter function.
const person1 = {
   _name: "Nicholas",

   get name() {
      console.log("Reading name");
      return this._name;
   },

   set name(value) {
      console.log("Setting name to %s", value);
      this._name = value;
   }
};

console.log(person1.name);   // "Reading name" then "Nicholas"

person1.name = "Greg";
console.log(person1.name);   // "Setting name to Greg" then "Greg"

This example defines an accessor property called name. There is a data property called _name that contains the actual value for the property.

The leading underscore is a common convention to indicate that the property is considered to be private, though in reality it is still public. The syntax used to define the getter and setter for name looks a lot like a function but without the function keyword. The special keywords get and set are used before the accessor property name, followed by parentheses and a function body.

Share This:    Facebook Twitter

Javascript Object properties

Detecting Properties

The in operator looks for a property with a given name in a specific object and returns true if it finds it.

console.log("name" in person1);   // true
console.log("age" in person1);    // true
console.log("title" in person1);  // false

Keep in mind that methods are just properties that reference functions, so you can check for the existence of a method in the same way.

const person1 = {
   name: "Nicholas",
   sayName: function() {
      console.log(this.name);
   }
};

console.log("sayName" in person1);  // true

In some cases, however, you might want to check for the existence of a property only if it is an own property. The in operator checks for both own properties and prototype properties, so you’ll need to take a different approach. Enter the hasOwnProperty() method, which is present on all objects and returns true only if the given property exists and is an own property.

const person1 = {
   name: "Nicholas",
   sayName: function() {
      console.log(this.name);
   }
};

console.log("name" in person1);                         // true
console.log(person1.hasOwnProperty("name"));            // true

console.log("toString" in person1);                     // true
console.log(person1.hasOwnProperty("toString"));        // false

Removing Properties

You need to use the delete operator to completely remove a property from an object.

const person1 = {
   name: "Nicholas"
};

console.log("name" in person1);  // true

delete person1.name;             // true - not output
console.log("name" in person1);  // false
console.log(person1.name);       // undefined

Enumeration

By default, all properties that you add to an object are enumerable, which means that you can iterate over them using a for-in loop. This example uses bracket notation to retrieve the value of the object property and output it to the console, which is one of the primary use cases for bracket notation in JavaScript.

var property;

for (property in object) {
   console.log("Name: " + property);
   console.log("Value: " + object[property]);
}

If you just need a list of an object’s properties, use Object.keys() method to retrieve an array of enumerable property names. Typically, you would use Object.keys() in situations where you want to operate on an array of property names and for-in when you don’t need an array.

var properties = Object.keys(object);

// if you want to mimic for-in behavior
var i, len;

for (i=0, len=properties.length; i < len; i++){
   console.log("Name: " + properties[i]);
   console.log("Value: " + object[properties[i]]);
}

Keep in mind that not all properties are enumerable. You can check whether a property is enumerable by using the propertyIsEnumerable() method, which is present on every object:

var person1 = {
   name: "Nicholas"
};

console.log("name" in person1);    // true
console.log(person1.propertyIsEnumerable("name"));  // true

var properties = Object.keys(person1);

console.log("length" in properties);    // true
console.log(properties.propertyIsEnumerable("length")); // false
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