Sunday, 7 March 2021

Javascript Properties in CSS

 Style LWC Component using javascript property values.


style.setProperty()


Using style.setProperty() to keep CSS Property Names Consistent in Javascript.


:host 


This allows you to select a custom element from inside its shadow DOM.



cssDemo.js 


import {LightningElement,api} from lwc';


export default class CssDemo extends LightningElement{

  @api backgroundColor;

  @api textColor;

  

  renderedCallback(){

    this.template.host.style.setProperty("--my-bg-color",this.backgroundColor);

this.template.host.style.setProperty("--my-text-color",this.textColor);

// base component style

this.template.host.style.setProperty("--sds-c-badge-color-background",this.backgroundColor);

this.template.host.style.setProperty("--sds-c-badge-text-color",this.textColor);

  }

  

}



cssDemo.css 


:host{

  --my-text-color : black;

  --my-bg-color : white;

}


.container{

  background : var(--my-bg-color);

  color      : var(--my-text-color);

}


.someOtherClass{

  border-color : var(--my-text-color);

}  


.slds-badge{

   background-color : var (--sds-c-badge-color-background,#ECEBEA);

   color : var(--sds-c-badge-text-color,#080707);

}  


Sunday, 7 February 2021

Ten principles of Apex Testing

 why we Test ?


1.Tests provide assurance of functionality.

2.Tests reduce cost of change.

3.Tests encourage modular,reusable code.

4.Tests help identify engineering and architectural bugs.

5.Tests help document expected behavior.

6.Test + code = less likely to produce bugs.


Principle #1 :

A Test without Assert methods isn't a test  it's a liability.


Three Assert methods built-in 


System.Assert(boolean-expression,'friendly message')

System.AssertEquals(expect,actual,'friendly message')

System.AssertNotEquals(expect,actual,'friendly message')


Every test method should include at least one assertion.


Good test methods includes more than one.

The most robust,and helpful test methods include two sets of Asserts.


Assert that you properly setup all your test data.

Assert that the given test data was properly mutated by your code.

Principle #2 :


Start (then) Stop , Collaborate and Listen


Test.startTest() and Test.stopTest() help facilitate testing.


Isolates your code from the proper setup of the test(s).


startTest() resets DML,CPU Time and other governor limits,ensuring any limits you hit come from your tested code.

stopTest() forces asynchronous code to complete.


 

Principle #3 (Positive Tests) :


you should write 'Positive Tests'.


Positive tests prove the expected behavior, which is to say they prove it does what you think it does.


 ex : 

   System.assertEquals(12,testValue,'Expected 5+7 to equal 12');

   

   

Principle #4 (Negative Tests) :


Negative tests prove that your code properly handles exceptions and errors.


The pattern works by calling method within a try/catch block in the test.

catch only the expected type of exception in the catch block.


Less intuitive but more powerful !.


At the very least, negatively test methods that utilize user data.


 ex : 

   Boolean didcatchProperException = false;

   Test.startTest();

   try{

     examplecode.divide(1,0);  

   } catch(exampleCodeException AWesomeEception){

     didcatchProperException =true;

   }

  Test.stopTest();

  System.assert(didcatchProperException,'Properly caught custom Exception);


Principle #5 (User Tests) :


User based tests prove your security model works like you think it does.


Tests with Users of different Roles/Profiles and Permission sets !.


The pattern works like this : Create a user with a given profile.

As needed assign permission sets.Test both positive and negative users.


ex (Positive User Test): 


     exampleCode drWho = new exampleCode();

  User u = AwesomeTestLib.getUserWithProfile('jediProfile');

      Account a =(Account) TestFactory.createSObject(new Account());

      Integer result;

      system.runAs(u){

    Test.startTest();

result = drWho.getBankAccount(a);

Test.stopTest();

  }   

System.assertNotEquals(result,null,'Expected the Doctor to have access to bank ');

 

ex (Negative User Test) :  

  

  exampleCode dalerk = new exampleCode();

  User u = AwesomeTestLib.getUserWithProfile('DalerkProfile');

      Account a =(Account) TestFactory.createSObject(new Account());

      Integer result;

      system.runAs(u){

    Test.startTest();

result = dalerk.getBankAccount(a);

Test.stopTest();

  }   

System.assertEquals(result,null,'Expected Dalerk to be blocked');

 

ex (Testing with Permission Set)


    exampleCode Claraoswald = new exampleCode();

  User u = AwesomeTestLib.getUserWithProfile('Standard User');

      UtilityClass.AssignUserToPermissionSet(u,'Companion');

  Account a =(Account) TestFactory.createSObject(new Account());

      Integer result;

      system.runAs(u){

    Test.startTest();

result = Claraoswald.canAccessTardis(a);

Test.stopTest();

  }   

System.assertNotEquals(result,null,'Expected ClaraoOswald who has Companion to have access to the Tardis');

 

Principle #6 (Use your own data) :


Always build your own test data.

If you created the data,you can precisely assert against it.

Unless you have to,never use @isTest(seeAllData=true)

List of Acceptable Reasons to use @seeAllData =true.


 Reason : you're unit testing Approval Processes.


TestFactory, An open source test data factory.

 

 Url : https://github.com/dhoechst/Salesforce-Test-Factory


 ex :

 Account a =(Account)TestFactory.createSobject(new Account());

 Opportunity o = (Opportunity)TestFactory.createSObject(new Opportunity(AccountId = a.Id));

 Account[] aList=(Account[])TestFactory.createSObjectList(new Account(),200);

 

Principle #7 (Use a domain specific helper lib) :


Use a sane naming convention. i.e: Get* returns generated test data matching the method name !.

Mark your test helper class as @isTest to ensure it's never called by live code.


Principle #8 (Mocking) :


Integration v. Unit tests


Integration tests test code in an execution context -

i.e. setup some data and execute the code within the context.


Unit tests focus on a single unit of code,not necessarily a complete function.


Mocks allow us to write true unit tests by 'mock' objects.


You get to setup the mock, and it's responses.


   Unit Test w/Mocks 

   Calls a mocked service

   Returns exactly what you asked it to.


use the excellent and amazing fflib_ApexMocks.

Code to interfaces so you can Mock it good.

   

Principle #9 (Write for testing) :


keep your methods to no more than 20 lines.

Keep method arguments to a minimum - no more than four.

Write your Visualforce controllers to use a single wrapper object.

 

Principle #10 (Use Continuous Integration):


Continuous Integration is the process that enforces a full and complete test run is triggered every time someone commit to your source repository. You are using Git right?

A number of tools are available for CI on the Salesforce1 platform.

Travis.ci,Drone.io,Jenkins,Bamboo and Codeship are some examples.

Sunday, 24 January 2021

Composite Graph API

 The Composite Graph API is a huge leap forward when you need to perform CRUD operations on a large number of related sObjects.

Not only does it increase the subrequest limit from 25 to 500, it also provides a number of optimizations that ensure records are processed efficiently and operations are rolled back if any steps are not completed.


Organize subrequests inside within a graph :


The body of a Composite Graph API request consists of a number of graphs, each of which may contain multiple composite subrequests. You can think of each graph as its own grouping of related sObject records.


Syntax : 


{

    "graphs": [

        {

            "graphId": "graphId1",

            "compositeRequest": [

                compositeSubrequest1, 

                compositeSubrequest2, 

                ...]

        },

        {

            "graphId": "graphId2",

            "compositeRequest": [

                compositeSubrequest3, 

                compositeSubrequest4, 

                ...]

        }

    ]

}


Grouping collections of sObjects into graphs enables you to get much more done with a single API call. One big advantage of this is no longer having to manage the orchestration of the deeper, more intricate relationships that are inherent to more complex graphs.


As with the Composite API, each subrequest contains a referenceId that can be used to relate records that follow the subrequest.In the example below, the Account record is upserted and the referenceId is set to Account. In the subrequest that follows, an order record is inserted and the Account__c field value is set to @{Account.Id} , which references the account that was just inserted.


{

  "graphId": "graph1",

  "compositeRequest": [

    {

      "method": "PATCH",

      "url": "/services/data/v49.0/sobjects/Account/ExternalAcctId__c/ID12345",

      // Reference Id used to relate records to the account

      "referenceId": "Account",

      "body": {

        "Name": "Trailblazers",

        "Website": "TrailblazerOutfiters.com"

      }

    },

    {

      "method": "POST",

      "url": "/services/data/v49.0/sobjects/Order__c",

      "referenceId": "newOrder",

      "body": {

        // Reference Id used to relate records to the order

        "Account__c": "@{Account.id}"

      }

    },

    {

      "method": "POST",

      "url": "/services/data/v49.0/sobjects/OrderItem__c",

      "referenceId": "newProduct",

      "body": {

        "Order__c": "@{newOrder.id}",

        "Product__c": {

          "External_Id__c": "EB1213"

        },

        "Qty_L__c": "1",

        "Price__c": "500"

      }

    }

  ]

}


Sunday, 10 January 2021

set own created date for the inserted salesforce test records in test class

 How to set created date for a test method in test class in salesforce?


System.Test allows you to set the created date/time of a record.

This is super helpful when inserting test data and you want some of it to appear to the older.


// Sets CreatedDate for a test-context sObject.

 syntax : setCreatedDate(recordId,createdDatetime)

 

 ex :

   @isTest   

 private class SetCreatedDateTest {  

   static testMethod void testSetCreatedDate() {  

     Account a = new Account(name='Test Account');  

     insert a;  

     Test.setCreatedDate(a.Id, DateTime.newInstance(2012,12,12));  

     Test.startTest();  

     Account myAccount = [SELECT Id, Name, CreatedDate FROM Account   

                WHERE Name ='Test Account' limit 1];  

     System.assertEquals(myAccount.CreatedDate, DateTime.newInstance(2012,12,12));  

     Test.stopTest();  

   }  

 }  

 

Key points:

1.All database changes are rolled back at the end of a test. You can’t use this method on records that existed before your test executed.

2.You also can’t use setCreatedDate in methods annotated with @isTest(SeeAllData=true), because those methods have access to all data in your org.

3.This method takes two parameters—an sObject ID and a Datetime value—neither of which can be null.


Sunday, 27 September 2020

Javascript Basics

 


1.Property Access :


what is an object ?


An object is a data structure.

we have key value pairs.we store our data in there.

And that data we store at those property names can be any type.



Accessing properties on an Object :


There are two ways to access properties on an object 


1.Dot Notation

2.Bracket Notation/ Square bracket Notation

Note : Always use Dot Notation.But if you're dealing with invalid identifier

or variables,use the Bracket notation.

Dot Notation :

Use can Assign and access properties on an object using Dot Notation 

ex : assignment with dot

var box={};

box.material ="cardboard";

var box = {"material":"cardboard"};


ex: access with dot



var box={};

box.material ="cardboard";


var cb = box.material;

console.log(cb);      //  cardboard


Brackets :


ex: var box ={};

    box["material"] = "cardboard";

console.log(box.material);    // cardboard

    console.log(box["material"]); // cardboard


ex : variables


     var box ={};

box["material"] ="cardboard";

var key = "material";

console.log(box[key]);  // "cardboard"


ex: expressions


    var box ={};

    box["material"]="cardboard";

    var func = function(){

  return "material";

}

   console.log(box[ func() ]);   // "cardboard"



ex :  

      var box ={};

      box['material'] ="cardboard";

      var key ='material';

      console.log(box['key']);   // undefined

  console.log(box.key);        // undefined

  console.log(box[key]);      // "cardboard"


Note : if property doesn't exist on object , so it returns undefined.


Dot notation :


1.Property identifies can only be alphanumeric (_ and $).

2.Property identifiers cannot start with number

3.Property identifiers cannot contain variables.

  ex: obj.prop_1, obj.prop$


Bracket Notation :


1.Property identifiers have to be a string or a variable that references a string.

2.It is okay to use variables,spaces and strings that start with numbers.

 ex: obj["1prop"],obj{"prop Name"]


summary :

1.Dot notation is faster to write and clearer to read.

2.Square bracket notation allows access to properties containing special characters and selection of properties using variables.

3.Bracket notation expects an expression which evaluates to a string.

4.The dot notation only works with property names which are valid identifier name.


Brackets : quotes('') required for strings,weired characters.

           quotes('') not required for variables,numbers and expressions.


Storing Data and Object-literal Notation :


we can store any data in our object.


 ex: 

    var box = {};

box["material"]="cardboard";

box["size"] = {

  "height" : 2,

  "width" : 80

};

box.area= function(){

   return box.size.height * box.size.width;

};

or 

box['area'] = function(){

   return box.size.height * box.size.width;

};


Access function :


ex :

   box["area"]();

    

   var func = 'area';

   box[func]();

   


Note :


1.Objects created using object literals are singletons.

This means when a change is made to the object,it affects that object across the entire script.


2.Object defined with the function constructor let us have multiple instances of that object.

This means change made to one instance, will not affect other instances.


Object literal Notation

  

 ex : 

    var box = {

material: "cardboard",

height    : 2,

width     : 80,

area    : function(){

   return this.height * this.width;

  }

};


what are the different ways you can add properties and values to objects?


--> dot notation and bracket notation.


which of these methods would you use if you wanted to add a property to an object that had a weired symbol ('&')?


--> must use bracket notation


what about if the property is a variable, how does that change the syntax ?


--> must use bracket notation, no quotes


 

Object Iteration :


1. for..in loop

    

ex : 

var box = {

material: "cardboard",

height    : 2,

width     : 80

};


  for (let key in box){

      console.log(key, box[key]);  // prints key and value 

   }    


2.with ES6 for..of using Object.entries


  ex : 

    var box = {

material: "cardboard",

height    : 2,

width     : 80

};


  for (let [key,value] of object.entries(box)){

      console.log(key,value);  // prints key and value 

   }       

 

Note : 

The keys,values and entries are 3 common lists to extract from a javascript objects.


1. The keys of an object is the list of property names.

2. The values of an object is the list of property values.

3. The entries of an object is the list of pairs of property names and corresponding values.


1.Object.keys() returns keys

2.Object.values() returns value

3.Object.entries() returns entries

 

or 


1.The keys are returned by Object.keys(object)

2.The values are returned by Object.values(object)

3.The entries are returned by Object.entries(object)




 

Arrays :

==========


Arrays are a special type of objects, with numbered indexes.


Array is an object which is used to store a collection of values or items in a single variable.


Arrays allow us to store values without needing to assign keys.


 ex :

  let box = [];

  box[0] = true;

  box[1] = 'meow';

  box.push({'hello':'goodbye'});


   

  console.log(box[0]);  // true;

  console.log(box[1]);   // 'meow'

  console.log(box.pop());  // {'hello':'goodbye'}

  

Note : pop() method remove an item from the end of an array.  

  

  console.log(box); // [true,'meow'];


  

Note : push() method append items to the end of an array.  

       you can use push() method to append more than one item/value to an array in a single call.


ex: 

// initialize array

let arr = ["Hi", "Hello", "Bonjour", "Hola"];


// append multiple values to the array

arr.push("Salut", "Hey"); 

   

 

 ex :       var box=[];

            box['size'] =9;

box['0'] = 'meow';

console.log(box) ; // ["meow", size: 9] 

console.log(box['size']) // 9

console.log(box[0]);      // 'meow'


Note : An array is an object that means you can add properties to it.


 ex :  var box=[];

       box['size']=9;

       box['0']='meow';

   console.log(box)  // ["meow", size: 9]

       box.size;  // 9

       box[0];   // 'meow'    

   

Iteration :


ex :


  var box=[];

  box['size'] =9;

  box['0']='meow';

  for(let key in box){

   console.log(key);    // 0,size

  } 


  for(let key in box){

   console.log(box[key]);    // meow,9

  } 


Native properties :


  ex : var box =[];

       box['0']='meow';

       box[3]={'babyBox':true};

       box['length']; // 4


Note : The array length property is keeping track of the numerical indices,

every time you add something to it.


  ex : 

       var box =[];

   box['0'] = 'meow';

   box[1] = {'babyBox': true};

   box[length]; // undefined


The length variable is not defined/declared .


ex : var box =[];

     box['0'] = 'meow';

     box[1] = {'babyBox': true};

     box[box.length-1];  // {babyBox: true}


How to add values & indices to arrays ?


1.bracket notation

2.bracket notation with variable

3.dot notation

4.native methods

5.length property


How to access values & indices to arrays ?


1.bracket notation

2.bracket notation with variable

3.dot notation

4.native methods

5.length property



Create an array 


 ex : let noiseArray =['purr'];


Add item to the beginning of an Array


 ex : noiseArray.unshift('hiss');


Add item to the end of an array.


 ex : noiseArray.push('meow');


Using bracket notation add item to an array.


ex :  noiseArray[3] ='growl';


Inspect an Array :


1. length of an array.


 ex : let totalitems = noiseArray.length;

 

 index starts from 0 so the last index is 1 less than the length.

 

 Nest the array in the object

 

  ex : animal.noises = noiseArray;

       console.log(animal);


What are the different ways you can add properties and values to arrays?


use bracket notation or native array methods    


Come up with two ways you can add an element to the end of an array, without knowing the exact length of the array.


 use arr.push() or arr[arr.length]



Functions :

==========


parameters are variables listed as a part of the function definition.


Arguments are values passed to the function when it is invoked.


The arguments object is an array-like construct which can be used to access arguments 

passed to the function even if a matching parameter isn't explicitly defined.


The "argument object" is an array-like object that stores all the parameters passed to a function.

even if the function declaration doesn't specify any parameters.


function argumentVar(parameter1, parameter2, parameter3){

  console.log(arguments.length); // Logs the number of arguments passed.

  console.log(arguments[3]); // Logs the 4th argument. Follows array indexing notations. 

}


argumentVar(1,2,3,4,5);

// Log would be as follows

// 5

// 4


ex :


function addAlltheNumbers(){

  var argsArray = Array.prototype.slice.call(arguments);

  return argsArray.reduce( (acc,cur) => acc + cur);

  

}

 

addAlltheNumbers(1543,3298,1729,1449,1435); // 10000


Constructor :


function AnimalMaker(name){

  return {

   speak : function (){

     console.log("my name is ", name);

   }  

  };


var myAnimal = AnimalMaker('tiger');


myAnimal.speak; // f(){ console.log("my name is ",name);}


myAnimal.speak(); // my name is tiger


ex :


function AnimalMaker(name){

  return {

   speak : function (){

     console.log("my name is ", name);

   }  

  };

}


var animalNames =['Sheep','Liger','Big Bird'];


var farm[];


for(let i =0; i < animalNames.length;i++){  

  farm.push(AnimalMaker(animalNames[i]));

}


for (let j=0; j<farm.length;j++){

  farm[j].speak();

}


ex :

  function AnimalTestUser(username){ 

     let args = arguments.length;

let otherArgs = [];

   if(args>1){

     for( let i=1;i<args;i++){

  otherArgs.push(arguments[i]);

}

   }

  

   return {

     username:username,

otherArgs:otherArgs

   };

  }

  

  

without arguments : 

   

  let myAnimal = AnimalTestUser('cow');

  console.log(  myAnimal.username); // cow


  

with arguments :


var testSheep = AnimalTestUser('CottonBall', {'loves dancing': true}, [1,2,3] );

console.log(testSheep);   ////{ username: 'CottonBall', otherArgs: [ {'loves dancing': true}, [1,2,3] ] }


ex: 


function AnimalCreator(username,species,tagline,noises){

  var animal = {

   username:username,

   species : species,

   tagline : tagline,

   noises : noises,

   friends : []

  };

  

  return animal;

}


let sheep = AnimalCreator('Cloud','sheep','you can count on me!',['baahhh','arrgg','chewchewchew']);


console.log(sheep);   

      // { username: 'Cloud', 

      //  species: 'sheep', 

      //  tagline: 'You can count on me!', 

      //  noises: ['baahhh', 'arrgg', 'chewchewchew'], 

      //  friends: []

      // }

   

 function addFriend(animal,friend){

     animal.friends.push(friend.username);

 } 

       

let cow = AnimalCreator('Moo','cow','got milk?',['moo','moooo','mooo']);


let llama= AnimalCreator('Zeny','llma','llll',['sdf','sdfsf']);


addFriend(sheep,cow);

addFriend(sheep,llama);


let myFarm = [sheep,cow,llama];

addFriend(cow,sheep);

addFriend(llama,cow);


function addMatchesArray(farm){

   for(let animal in farm){

   farm[animal].matches=[];

   }

}

addMatchesArray(myFarm);

console.log(myFarm[0]);


function giveMatches(farm){

  for(let animal in farm){

   farm[animal].matches.push(farm[animal].friends[0]);

   

  }

}


giveMatches(myFarm);

console.log(myFarm[0]);


Nesting :

===========

 ex: var box = {};

     box.innerBox={};

 

( or)

var box = {"innerBox":{}};

   ex: 

    var box ={};

    box['innerBox']={};


ex :

    var box ={};

    box['innerBox'] ={};

    box['innerBox']['full']=true;


    (or)

    var box = { 'innerBox':{full:true}};


Scope :

=========

Scope is created dynamically whenever we call the function.


A function has access to its own local scope variables.


Different Types of Scopes :


1.Global Scope

2.Function Scope(local scope)

3.Module Scope

4.Block Scope

5.Lexical Scope


Scope is the region of the codebase over which an identifier is valid.


1.Global Context :


Variables declared directly in the global context, in which case they are added as properties on the global context.


Global Variables are available for the lifetime of the application.


There is only one Global scope throughout a javascript document.

A variable is in the Global scope if it's defined outside of a function.


Note : You can also access and alter any variable declared in a global scope from any other scope.


ex : 

    function f1(){

console.log(' I am global function');

}

f1();        // I am global function

window.f1(); // I am global function

 ex: 

     var x ='global !';

     function encapsulate(){

   z =' global here, too !';

   window.y='also global';

}  


2.Function Scope :


Variables defined in a function are visible everywhere within the function,

but are not visible outside of the function.


Variables declared within a function are in the local scope.

Local scope is also called function scope because local scope is created by functions in Javascript.


ex: 

     var func = function(){

    var local = true;

}


Note : 

1.Variables declared with 'var' have only function scope.

2.Variables declared with 'var' hoisted to the top of their scope.  



3.Block Scope :


A block is a set of opening and closing curly brackets.


In ES6, 'let' and 'const' keywaords allow developers to declare variables in the block scope,

which means those varaiables exist only within the corresponding block.


A block scope is the area within 'If','switch', conditions or 'for' and 'while' loops.


ex : function foo(){

      if(true){

    var fruit1 ='apple';       // exist in function scope

let fruit2 ='banana';      // exist in block scope

const fruit3='strawberry'; // exist in block scope

  }

  console.log(fruit1);

  console.log(fruit2);

  console.log(fruit3);

 

    }


// Result :

   // apple

   // error: fruit2 is not defined

   // error: fruit3 is not defined


Block scope is everything inside a set of braces.

   ex : { a block scope here }


Note : A Block scope is sometimes the same as a function scope.

so, at the top of a function's code, a block scope will be the same as a function scope.


ex : 

     function test(x){

// this is both a block scope and a function scope

let y = 5;

if(x){

   // this is a smaller block scope that is not the same as the function scope

   let z=1;

  }  


Note :

'var' is not limited to the curly brackets.

'var' is a function scope.

Function scope is within the function.

 

4.Lexical scope :

Lexical scope means the children scope have the 

access to the variables defined in the parent scope.


The children functions are lexically bound to the execution context of their parents.


This lexical scope is heavily used in closures in javascript.


ex : 

      function outerScope(){

    var name ='Juan';

function innerScope(){

  console.log(name ) ;    // Juan

}

    return innerScope;

  }

  

  const inner = outerScope();

  inner(); 


5.Module scope 

  With the introduction of modules in ES6, it was important for variables in a module to

  not directly affect variables in other modules.

  

  Modules create their own scope which encapsulate all variables created with

  var,let or const similar to the function scope.

  

  A module is just a file which can be imported from other modules (or files) through the help of directives

  like 'export' and 'import'.

       

 

Parent vs Child scope :


 ex : 

   function blender ( fruit){

     var b= fruit;

var y = 'yogurt';

function bs(){

   var x='asdf';

  console.log( b + ' and ' + y + ' Makes '+b+' swirl');

}

 

bs();

   

   } 

   

  blender('blueberry');  // blueberry and yogurt Makes blueberry swirl

  

  Note : child  scope can access variables from parent scope. but parent scope cannot access from child scope


 

Precedence :


The local variable always get priority over the global variables with same name.


if you declare a local variable and a global variable with the same name,

the local variable will take precedence when you use it inside a function.

This type of behavior is called shadowing(variable shadowing).


  ex : 

       var g ='global';

  

      function go(){

    var l ='local';

var g ='in here !';

console.log( g + " inside go");

  } 

      go(); // in here inside go   

     console.log( g + " outside go'); // global outside go

 

Note :  

The local variables always get priority over the global variables with same name.


Summary :


1. A function has access to its own local scope variables


 ex : var ACTUAL;

      var fn = function(){

    var name='inner';

ACTUAL=name;

console.log(ACTUAL);

  }

      fn();   // inner

  console.log(ACTUAL); // inner


2.Inputs to a function are treated as local scope variables.

  ex : 

       var ACTUAL;

   var fn=function(name){

     ACTUAL=name;

console.log('local scope',ACTUAL);

   }

   fn('inner');

  console.log('outer scope',ACTUAL); 

  Result :

     // local scope inner

     // outer scope inner

 

3.A function has access to the variables contained within the same scope that function was created in.


ex :  var ACTUAL;

      var name ='outer';

  var fn = function(){

    ACTUAL=name;

  }

  fn();

  console.log(ACTUAL); // outer


4. A function's local scope varaiables are not available anywhere outside that function.


ex : var firstFn = function(){

      var localToFirstFn = 'inner';

     }

     firstFn();

     console.log(localToFirstFn); // Uncaught ReferenceError: localToFirstFn is not defined


5.A function's local scope variables are not anywhere outside that function, regardless of the context it's called in.


 ex:  

     var ACTUAL;

      var firstFn=function(){

      var localToFirstFn = 'first';

  secondFn();

  }  

    var secondFn = function(){

   ACTUAL = localToFirstFn;

}

secondFn();  // Uncaught ReferenceError: localToFirstFn is not defined


Note : since secondFn does not have access to the localToFirstFn variable.

    

firstFn(); // Uncaught ReferenceError: localToFirstFn is not defined

Note : calling the firstFn(which in turn calls the secondFn) should also throw,

since it is calling context of secondFn has no influence over its scope access rules.


6. If an inner and outer variable share the same name,and the name is referenced in the inner scope,

the inner scope variable masks the variable from the outer scope with the same name.

This renders the outer scope variables inaccessible from anywhere within the inner function block.


ex : var ACTUAL;

     var sameName='outer';

     var fn = function(){

  var sameName='inner';

   ACTUAL=sameName;

};

    fn();

    console.log(ACTUAL); //  inner

7. if an inner and an outer variable share the same name,and the name is referenced

in the outer scope,the outer value binding will be used.


 ex : 

      var ACTUAL;

      var sameName='outer';

      var fn = function (){

    var sameName ='inner';

  }

      fn();

      ACTUAL=sameName;

      console.log(ACTUAL); // outer

  

8.A new variable scope is created for every call to a function,

as exemplified with a counter.


 ex : var ACTUAL;

      var fn = function(){

   var innerCounter = innerCounter || 10;

   innerCounter = innerCounter + 1;

   ACTUAL = innerCounter;

  } 

  fn();

  console.log(ACTUAL);  // 11

  fn();

  console.log(ACTUAL);  // 11

  

9.A new variable scope is created for each call to a function, as 

exemplified with uninitialized string variables.


  ex : var ACTUAL;

       var fn = function(){

     var localVariable;

if(localVariable === undefined){

   ACTUAL='alpha';

} else if (localVariable === 'initialized'){

  ACTUAL ='omega';

}

     localVariable='initialized';

   }

   

   fn();

   console.log(ACTUAL);  // alpha

   fn();

   console.log(ACTUAL);  // alpha


10. An inner function can access both its local scope variables and variables in its containing scope,

provided the variables have different names;


 ex : var outerName ='outer';

      var fn =function(){

   var innerName ='inner';

   ACTUAL = innerName + outerName;

  }  

  fn();

  console.log(ACTUAL); //innerouter

  

11. Between calls to an inner function, that inner function retains access to a variable in an outer scope.

Modifying those variables has a lasting effect between calls to the inner function.


  ex : var ACTUAL;

       var outerCounter = 10;

       var fn = function () {

      outerCounter = outerCounter+1;

  ACTUAL=outerCounter;

   }

       fn();

       console.log(ACTUAL);  // 11

       fn();

       console.log(ACTUAL);  // 12


12.The rule about retaining access to variables from an outer scope still applies,

even after the outer function call ( that created the outer scope) has returned.


  ex :  var ACTUAL;

        var outerFn = function(){

  var counterInOuterScope = 10;

  

  var innerIncrementingFn = function(){

    counterInOuterScope = counterInOuterScope + 1;

ACTUAL=counterInOuterScope;

  }

  

  innerIncrementingFn();

  console.log(ACTUAL);       // 11

  innerIncrementingFn();

   console.log(ACTUAL);      // 12

   window.retainedInnerFn = innerIncrementingFn;   

  

};

console.log(window.retainedInnerFn); // undefined

outerFn();

console.log(window.retainedInnerFn);  // function

window.retainedInnerFn();

console.log(ACTUAL);                  // 13

 

Closure :

===========

A closure happens when you return a function from inside of the function,

and that inner function retains access to the scope.


The closure has three scope chains :


1.it has access to its own scope.

2.it has access to the outer function scope.

3.it has access to the global scope.


Note : The inner function will have access to the variables in the outer function scope, even after the outer function has returned.


 ex : 

      var closureAlert = function(){

    var x = " Help! I'm a variable stuck in a closure!";

var alerter = function (){

  console.log(x);

}

setTimeout(alerter,1000);

console.log('will still run right after');

  };

   closureAlert();


Result :

  will still run right after

  Help! I'm a variable stuck in a closure!

    

 ex :

      var closureAlert = function (){

    var x = 0;

var alerter = function(){

  console.log(++x);

};

return alerter;

  };

   

      var funcStorer = closureAlert();

      var funcStorer2 = closureAlert();

      funcStorer(); // 1

      funcStorer();  // 2

  

  funcStorer2(); // 1


 ex : 

      var add = function(num){

    var num1=num;

var addToNum1 = function(num2){

  return num1 + num2;

};

return addToNum1;

  };

  

  var add5 = add(5);

  add5(2);    // 7

      add5(3);    // 8


Closure Object :


  ex :

  

   function counter(){

    var n =0;

return {

count : function() { return ++n;},

reset : function() { n =0; }

};   

   };   

  var myCounter = counter();

   myCounter.count();  // 1

   myCounter.count();  // 2

   myCounter.count();  // 3


Callbacks :

============


1. Module pattern :


Module pattern is a commonly used design pattern which is used to wrap a set of variables 

and functions together in a single scope.


Module pattern is used to define objects and specify the variables and the functions that can be accessed 

from outside the scope of the function.


we expose certain properties and function as public and can also restrict the scope of properties and functions within the object itself,making them private.

This means that those variables cannot be accessed outside the scope of the function.we can achieve data hiding an abstraction using this pattern in the javascript.


Benefits of module pattern :


1.Maintainability : 

2.Reusability



Higher-Order Functions :


1.takes a function as an input (argument)


  ex : element.addEventListener("click",function(){

        console.log("element clicked!");

       });  

2.Returns a function as an output


  ex : var add = function(num){

  

    var num1=num;

return addToNum1 = function(num2){

   return num1 + num2;

}

  };

  

Callbacks :


we can pass functions as parameters to other functions and call them inside the outer functions.


  ex :  var ifElse = function(condition, isTrue,isFalse){

             if(condition){

   isTrue;

}else{

   isFalse;

}

         }; 


          ifElse(true,function(){ console.log(true);},

                      function(){ console.lof(false);}

                 );



 ex : 

      const message = function(){

     console.log("this message is shown after 3 seconds");

  } 

  

  setTimeout(message,3000);

  

Note : The message function is a callback function.


 ex : Anonymous function 


      setTimeout(function(){

     console.log(" This message is shown after 3 seconds");

  },3000); 


The callback function here has no name and a function definition without a name in javascript

is called as an "anonymous function".   


  ex : callback as an Arrow function 

  

       setTimeout(()=>{

      console.log("this message is shown after 3 seconds");

   },3000);


you can write the callback function as an ES6 arrow function.


 ex : Events    

 

     <button id="callback-btn">Click here</button>

document.queryselector("#callback-btn")

      .addEventListener("click", function() {    

      console.log("User has clicked on the button!");

    });


callback  functions are used for event declarations in javascript.

Sunday, 20 September 2020

Arrays and Collections in Javascript

 


The Array.of() method creates a new Array instance with any number of arguments,regardless of their type.


ex : 

  let monthlySales = Array.of(12,9,3);

  let monthlyLabels = Array.of('Oct','Nov','Dec');

  let deptSales = Array.of(12,9,3);

  let deptLabels = Array.of('Hiking','Running','Hunting');

  

Using the spread Operator with array 


ex : 

     let monthlySales = Array.of(12,9,3);

 

let yearlyTotal= addYearlyTotal(...monthlySales);

 

 

function addYearlyTotal(a,b,c){

    return a+b+c;

}


ex :

      let octNums = Array.of(1200,1000,9000);

let novNums = Array.of(1100,2000,9000);

let decNums = Array.of(4000,1000,5000);

 

let total = Array.of(...octNums,...novNums,...decNums);


Using Array.find and Array.findIndex to find a value


ES6 Array.find() and Array.findIndex() methods which provide easy ways to search for an element in Javascript arrays.


Array.find() method returns the value of the first element in an array that passes a given test.


Note : 

1.Test must be provided as a function.

2.find() method executes a callback function once for each element in the array until it finds a value that returns true.

3.If nothing passes, undefined is returned.

4.find() does not mutate or change the original Array.


ex : 

     let monthlySales=Array.of(500,9000,3000)

     let firstThousand = monthlySales.find(element => element > 1000);

     console.log(firstThousand); // 9000


findIndex() returns the index of the first element in the array that satisfies the given test.


ex :  

let monthlySales=Array.of(500,9000,3000);

     let firstThousand = monthlySales.findIndex(element => element > 1000);

     console.log(firstThousand); // 2

 

Array.fill() :


you want to take an array and then just put all the numbers back to zero.


  ex : 

   let monthlySales=Array.of(500,9000,3000);

   monthlySales.fill(0);

   console.log(monthlySales); // [0, 0, 0]


Methods for Iterating through Arrays :


Array.forEach() is an Array method that we can use to execute a function on each element in an array.

it can only be used on Arrays,Maps and Sets.


ex :

const arr = ['cat', 'dog', 'fish'];

arr.forEach(element => {

  console.log(element);

});

// cat

// dog

// fish


ex :

       let monthlySales=Array.of(500,9000,3000);

       let yearlyTotal =0;

   

      function addYearlyTotal(x){

    yearlyTotal = x + yearlyTotal;

  }  

  

  monthlySales.forEach(addYearlyTotal);

  

  console.log(yearlyTotal);  // 12500


When using forEach, we simply have to specify a callback function.

This callback will be executed on each element in the array.


sets && WeakSets :


Sets enables you to store unique values of any type, whether primitive values or object references.


you can determine the size of the set by using the Size property.


ex : 

  const set1 = new Set(); 

  set1.add(42);

      set1.add('forty two');

      set1.add('forty two');

  console.log(set1.size);  // 2


Set Methods :

Add,clear,Delete,Entries,forEach,Has,Keys,Values


 ex : add

     

      const set1 = new Set();

  set1.add('3000');

  

  const test = new Set();

  test.add(5).add(4);

  

  const set2 = new Set(['5000','2000']);

   

 ex: delete


     const monthlySales = new Set();

monthlySales.add('5000');

monthlySales.delete('5000');


Iterating a set :

  ex :

    const monthlySales = new Set();

monthlySales.add('5000');

 

  for(let total of monthlySales)

  console.log(total);            // 5000

  

  monthlySales.forEach(element => {

    console.log( element);        // 5000

  });


Note : Array.from enables creating a new shallow-copied array from an array-like object 

or an iterable(Array,String,Map,Set) object.

  

  ex :

   const cars = new Set(['Porsche', 'Ferrari']);

   const carsCopy = Array.from(cars);

  console.log(carsCopy); // ["Porsche", "Ferrari"]

  

Set vs WeakSet :


WeakSet :

1.Only contains objects.

2.No primitive data types.

3.Objects are held 'weakly'.

4.Not iterable

5.No access to size property

6.Garbage collected


Weakset Methods : Add,Delete and Has


 ex : 

     const categories = new WeakSet();

  categories.add({category:'Hiking'});

  

  let running= { category:'Running'};   

      categories.add(running);

  console.log(categories.has(running)); // true



Using Maps in Javascript:


Map uses key-value pairs and keeps the original insertion order of the keys.

Any value (objects and primitive values) may be used as either a key or a value.


Map Methods :


Set,delete,clear,get,entries,forEach,has,keys,values


  ex: 

   const monthlySales = new Map();

   monthlySales.set('newsale',5000);

   console.log(monthlySales);        // {"newsale" => 5000}

   

   console.log(monthlySales.get('newsale')); // 5000


   console.log(monthlySales.has('newsale'));  // true

   

   monthlySales.delete('newsale');

   

Iterating through a Map :

 

   ex: 

     const monthlySales = new Map();

monthlySales.set('Oct',5000);

 

let arraydata= Array.from(monthlySales.keys());

console.log(arraydata);     // ["Oct"]


monthlySales.forEach( function(sale){

  console.log(sale);                    // 5000

});


     for(let amount of monthlySales.values()){

console.log(amount);                      // 5000

}


Weakmap :


1.Keys must be objects.

2.Object are held "weakly".

3.Not iteratable

4.Garbage collected

5.WeakMaps are not enumerable


WeakMap Methods : Set,get,has and delete


 ex : 

      const monthlySales = new WeakMap();

   

   let salesA= { a:[1,2]};

   monthlySales.set(salesA,'Hiking');

   console.log(monthlySales);   // {{...} => "Hiking"}


Saturday, 19 September 2020

Spread Operator in javascript

 1.Copy / concatenate arrays

2.pass to constructors

3.shallow copy objects

4.Call function with multiple parameters


The spread operator expands any iterable object such as a string

or an array into another array.


The spread operator used for passing multiple arguments to a method.


The syntax uses the ellipsis symbol (...) or three dots.


Always on the right-side of an equal sign.


Note : IE and Edge do NOT support spread operator.


ex : String to array

   let productNumber = "FR-R92B-58";

   let values =[...productNumber];

   console.log(values);  // ["F", "R", "-", "R", "9", "2", "B", "-", "5", "8"]


ex : Copy array 

    let arr = [1,2,3];

    let arr2= [...arr];

    // make changes to duplicated array

arr2.push(4);

arr2[0]=99;

 

   console.log(arr);    // [1, 2, 3]

   console.log(arr2);   //  [99, 2, 3, 4]


ex: copy an array of objects


   let _products = [

      {

        productID: 680,

        name: "HL Road Frame - Black, 58",

        productNumber: "FR-R92B-58",

        color: "Black",

        standardCost: 1059.31,

        listPrice: 1431.50

      },

      {

        productID: 707,

        name: "Sport-100 Helmet, Red",

        productNumber: "HL-U509-R",

        color: "Red",

        standardCost: 13.08,

        listPrice: 34.99

      },

      {

        productID: 709,

        name: "Mountain Bike Socks, M",

        productNumber: "SO-B909-M",

        color: "White",

        standardCost: 3.3963,

        listPrice: 9.50

      }

    ];


      // Careful with object arrays

      // The array is copied, but the underlying objects are still accessed by reference

      let diff = [..._products];

      diff[0].productID = 999;

      console.log(_products[0].productID);  // 999

      console.log(diff[0].productID);     // 999


Note : objects are not copied by value.objects copied by reference.


ex : concatenate two arrays 


  let _products = [

      {

        productID: 680,

        name: "HL Road Frame - Black, 58",

        productNumber: "FR-R92B-58",

        color: "Black",

        standardCost: 1059.31,

        listPrice: 1431.50

      },

      {

        productID: 707,

        name: "Sport-100 Helmet, Red",

        productNumber: "HL-U509-R",

        color: "Red",

        standardCost: 13.08,

        listPrice: 34.99

      },

      {

        productID: 709,

        name: "Mountain Bike Socks, M",

        productNumber: "SO-B909-M",

        color: "White",

        standardCost: 3.3963,

        listPrice: 9.50

      }

    ];


    let _newProducts = [{

      productID: 712,

      name: "AWC Logo Cap",

      productNumber: "CA-1098",

      color: "Multi",

      standardCost: 6.9223,

      listPrice: 8.99

    },

    {

      productID: 821,

      name: "Touring Front Wheel",

      productNumber: "FW-T905",

      color: "Black",

      standardCost: 96.7964,

      listPrice: 218.01

    }

    ];


     // Concatenation

 

     let allProducts = _products.concat(_newProducts);

      console.log(allProducts.length);                   // 5


      let spProducts = [..._products, ..._newProducts];

      console.log(spProducts.length);                    // 5



Using Spread to pass Parameters to a Constructor


we can also use the spread to help us build objects that, where we pass in multiple

values to the constructor.


ex :


     // Use with 'new'

      let dt = new Date(2019, 10, 15);  // 15 Nov 2019

      console.log(dt);                  // Fri Nov 15 2019 00:00:00 GMT+0530 (India Standard Time)

      

      let dateFields = [2019, 11, 15];  // 15 Dec 2019

      dt = new Date(...dateFields);    

      console.log(dt);                // Sun Dec 15 2019 00:00:00 GMT+0530 (India Standard Time) 


Pass Parameters to a Function :


 ex : using spread for function arguments


    

      let args = [1, 2, 3];

      multipleParams(...args);

  

   function multipleParams(arg1, arg2, arg3) {

      console.log(arg1);

      console.log(arg2);

      console.log(arg3);

      console.log("");

    } 


Output :

1

2

3


Shallow copy on object literals :


The useful feature of the spread operator is used to perform a shallow copy on object literals.


 ex :

   let product = {

        productID: 680,

        name: "HL Road Frame - Black, 58",

        standardCost: 1059.31,

        listPrice: 1431.50

      };


      // The following performs a shallow-copy

      // Similar to Object.assign()

      let prod2 = { ...product };


      // Change the newly copied object

      prod2.productID = 999;


      // Display the objects

      console.log(product);           // {productID: 680, name: "HL Road Frame - Black, 58", standardCost: 1059.31, listPrice: 1431.5}

      console.log(prod2);             // {productID: 999, name: "HL Road Frame - Black, 58", standardCost: 1059.31, listPrice: 1431.5}


      // Display the changed value

      console.log("");

      console.log(product.productID);  // 680

      console.log(prod2.productID);    // 999