Tuesday 19 April 2022

How to access Elements in LWC?

 To access elements rendered by component we need to use template property.

Access element from tag. <h1>Element Inside H1 Tag </h1>
const h1Element = this.template.querySelector('h1');
Console.log(h1Element.innerText ); // It will print "Element Inside H1 Tag"

We can apply style sheet after getting DOM element dynamically. 
h1Element.style = 'color:red;border-style: solid;'

Accessing element using class.
const userElements =  this.template.querySelectorAll('.name');
It will return node list (multiple items that is why  querySelectorAll is being used.)

We can set attributes to each element of node list dynamically or apply style sheet.
Array.from(userElements).forEach(item=>{
            console.log(item.innerText);
            item.setAttribute('title',item.innerText);
            item.style = 'background-color: black;'
        })

Note - Dont use Id selector with query selector in LWC

What is the use of lwc:dom = 'manul'
When we want to append html element dynamically to an element from JavaScript at that time lwc:dom directive required. it just tell LWC engine that html element going to added dynamically.

 <div class="childElement" lwc:dom="manual"> </div>

 const childELement = this.template.querySelector('.childElement')
        childELement.innerHTML = '<p>I am a Child DOM</p>';

What is shadow DOM?

 What is DOM ?

DOM - Document Object Model is a programming API for HTML or XML component, It defines logical structure of documents and the way document is accessed and manipulated. Basically the DOM is tree structure representation of web page.

What is Shadow DOM ?

Shadow DOM brings encapsulation concept to DOM. It enables to link hidden separate DOM to an element.

Benefits: DOM query, CCS rules and event propagation does not cross shadow boundary, hence creating encapsulation.

Basically when we try fetch all the DOM using query selectors, we will not get DOM elements for child component in parent component.

When we apply style sheet to DOM of parent component, there will be no impact to child component DOM.

Event propagation will not work from child to parent or vice versa by default. 

How to attach shadow DOM to element ?

<script>

    const element = docuement.queryselector('#elementId');

    const shadowRoot = element.attachShadow({mode:'open'});

    shadowRoot.innerHTML = '<p>I am a shadow DOM</p>'

</script>

How to invoke one LWC component from another ?

 Adding one LWC component within body of another LWC component  is known as component composition. It allows building complex component from simper building block component.

How to refer child component from parent component ?
1. childComponent            <c-child-component></c-child-component>

2. childComponentDemo       <c-child-component-demo></c-child-component-demo>

3. childComponentLWC         <c-child-component-l-w-c></c-child-component-l-w-c>

This naming convection known as kebab case. Replace capital letter with small and prefixed with hypen.

Advantages - Defining smaller component will make testing easy and reusability. 

Tuesday 5 April 2022

Template Looping in LWC

 There are 2 types of template looping in LWC

1. for:each
2. iterator

For Each
<template for:each={array} for:item="currentItem" for:index="index">
// we can add repeatable components
</template>

Note- 
1. for:each attribute take array as input
2. for item represent the current item of the loop, currentItem is the alias name, we can name to anything.
3. for:index holds index of current element of an array.

Importance of Key attribute in Template loop
Key is a special string/integer attribute required to be included to first element inside template when creating list of elements.
Key help LWC engine to identify which items added,removed or modified.
Key must be string or integer, It cant be object.
Array Index cant be defined as key.

<template>
    <lightning-card title="Best Companies">
        <div class="slds-m-around_medium">
            <template for:each={companyList} for:item="company">
                <ul key={company} class="slds-has-dividers_around-space">
                    <li class="slds-item">{company}</li>            
                    </ul>
            </template>
        </div>
    </lightning-card>
</template>
java script 
import { LightningElement } from 'lwc';

export default class Looping extends LightningElement {
    companyList = ['Google','Meta','Amazon','Salesforce','Signature Healthcare']
}

Iterator
To apply special behavior to the first or last element of list, iterator is preferable over for: each.
<template iterator:iteratorName={array}>
// here is repeating elements
</template>

Note
1. Iterator is a keyword to tell LWC engine its iterator loop.
2. IteratorName is the alias name, holds current element of array.
3. array is data on which loop is going to be executed.

Properties of Iterator
Value- the value of item of the array. Use this property to get array properties. Iteratorname.value.propertiesname
index: index of current item of array. iteratorname.index
first: Boolean(true/false) value indicates whether element is the first element of array. iteratorname.first
last: Boolean value indicates whether element is the last element of array. iteratorname.last

<template> 
<lightning-card title="CEO List">
        <div class="slds-m-around_medium">
            <template iterator:ceo={ceoList}>
                <ul key={ceo.value.id} class="slds-has-dividers_around-space">
                    <template if:true={ceo.first}>
                        <div class="slds-box slds-theme_shade">
                            <strong> List of Top compaies and Ceo Details</strong>
                        </div>
                    </template>
                    <li class="slds-item">
                        <Strong>{ceo.value.company}</Strong>                  
                        {ceo.value.name} {ceo.value.age} {ceo.value.salary}
                    </li>
                    <template if:true={ceo.last}>
                        <div class="slds-box slds-theme_shade">
                            <strong> Thank you</strong>
                        </div>
                    </template>
                    </ul>
            </template>
        </div>
    </lightning-card>
</template>

Javascript code
import { LightningElement } from 'lwc';

export default class Looping extends LightningElement {
    ceoList = [
        {id:1,name:'Sundar Pichai',age:49,salary:'2m',company:'Google'},
        {id:2,name:'Mark Zuckerberg',age:37,salary:'12B',company:'Meta'},
        {id:3,name:'Andy Jassy',age:54,salary:'35B',company:'Amazon'},
        {id:4,name:'Marc Benioff',age:57,salary:'26m',company:'salesfoce'},
        {id:5,name:'Joe Steier',age:58,salary:'500k',company:'SignatureHealthcare'},
    ]
}

Sunday 3 April 2022

Conditional Rendering in LWC?

 There are 2 special directive which is being used for conditional rendering of DOM element.
  1. if:true 
  2. if:false

 <template if:true={expression}>
    Render when expression is true
 </template>
 
  <template if:false={expression}>
    Render when expression is false
 </template>

Notes - 
1. Expression can be JavaScript property
2. Can be property of an object defined in JavaScript. example {employee.name}
3. Ternary operator can not be used inside expression.
4. Array also can not be used in the expression.
5. To use computed value use getters. 

Here is component code which have if-true if-false also computed expression in if-directive.
<template>
    <lightning-card title="Conditional Rendering">
        <div class="slds-m-around_medium">
            <lightning-button
            variant="brand"
            label="Show Data"
            title="Show Data"
            onclick={handleClick} class="slds-m-left_x-small">
            </lightning-button>
            <template if:true={isVisible}>
                <div >This is If-true directive example</div>
            </template>
            <template if:false={isVisible}>
                <div >This is If-false directive example,
                    Please click Button to see if-true content</div>
            </template>
            <lightning-input type="text" label="Enter Text" onkeyup={changeHandler}>

            </lightning-input>
            <template if:true={helloCheck}>
                <div>Congratulations you typed correctly. {typedValue}
                </div>
            </template>
        </div>
    </lightning-card>
</template>
Java script code
import { LightningElement } from 'lwc';

export default class HelloConditionalRendering extends LightningElement {
    isVisible = false;
    typedValue;
    handleClick(){
        this.isVisible = true;
    }
    changeHandler(event){
        this.typedValue = event.target.value;
    }
     get helloCheck(){
         return this.typedValue === "Hello";
     }
}