Naga Angular Js React
Naga Angular Js React
Important :
In interviews, mostly interviewers will focus on 5 areas.
It means all type checks are done at run time ( When program is executing ).
So, we can just assign anything to the variable and it works fine.
let a;
a = 0;
console.log(a) // 0
a = "Hello"
console.log(a) // "Hello"
String
number
boolean
null
undefined
Bigint
Non-Primitive datatypes:
Object
Array
Date
In javascript, variables and functions can be used before declaring it. The
javascript compiler moves all the declarations of variables and functions on
top. so there will not be any error. This is called hoisting.
👉 Interview Tip: Mention buzz word temporal dead zone in above answer so that
interviewer will ask What is temporal dead zone. 😉
Ref: https://stackabuse.com/hoisting-in-javascript/
6. What are the differences let, var and const ? (Most asked)
Scope:
Variables declared with var are function scoped.( available through out the
function where its declared ) or global scoped( if defined outside the
function ).
Reassignment:
Hoisting:
let and const - gets hoisted to the top of the scope but does not get
assigned any value.(temporal dead zone)
3. Destructuring assignment
4. Default parameters
5. Template literals
8. Classes
9. Modules
👉 Interview Tip: Here try to explain definations (provided in below questions) for
these features so that you can kill 2-3 min of interview time 😉
3. Arrow function does not have their own this. Instead, they inherit this from the
surrounding code at the time the function is defined.
4. Arrow functions cannot be used as constructors. Using them with the 𝙣𝙚𝙬
keyword to create instances throws a TypeError.
👉 Note: Arrow functions + this combination questions will be asked here. Please
explore on this combinations.
Uses:
let x = [1,2];
let y = [3,4];
function createExample(arg1,arg2){
console.log(arg1,arg2);
}
createExample(…a)
👉 Interview Tip: Practice the above examples mentioned and showcase them in
interviews to make interviewer think that you are a practical person. 😉
This is useful when we dont know how many parameters a function may receive
and you want to capture all of them as an array.
function Example(...args){
console.log(args)
}
const user = {
"age": 10,
"name": "Saikrishna"
}
Map is the collection of key value pairs Set is a collection of unique values
Eg: Eg:
O/P O/P
[”name”,”saikrishna”] 1
[”id”,”1”] Saikrishna
Ref: https://javascript.info/map-set
Modules can be imported and exported using import and export statements.
function changeNum(value) {
value = 20;
console.log(value); // Output: 20
}
changeNum(num);
console.log(num); // Output: 10
addToArr(arr);
console.log(arr); // Output: [1, 2, 3, 4]
map transforms each element of an array and creates a new array which
contains the transformed elements. whereas filter will creates a new array with
only those elements which satisfies the specified condition.
map method will return a new array with the transformed values. forEach
method does not return a new array.
map method can be used with other array methods like filter method. whereas
forEach method cannot be used with other array methods as it does not return
any array.
for-of:
https://stackoverflow.com/questions/29285897/difference-between-for-in-and-
for-of-statements?answertab=scoredesc#tab-top
It will return the first element of array that passes specified condition.
function findMethod(){
let arr = [{id:1,name:"sai"},{id:2,name:"krishna"}];
let data = arr.find(x=> x.id==2)
console.log(data)
}
findMethod()
Output:
{id:2,name:"krishna"}
findIndex:
It will return the index of first element of an array that passes the specified
condition.
findMethod()
Output:
2
Pure functions are the functions which will return same output for same
arguments passed to the function.
function greeting(name) {
return `Hello ${name}`;
}
console.log(greeting("Saikrishna Nangunuri"));
Impure Functions:
Impure functions are the functions which will return inconsistent output for
same arguments passed to the function.
Ref: https://www.scaler.com/topics/pure-function-in-javascript/
Call method will invokes the function immediately with the given this value and
allow us to pass the arguments one by one with comma separator.
Apply method will invokes the function immediately with given this value and
allow us to pass the arguments as an array.
Bind method will return a new function with the given this value and
arguments which can be invoked later.
Brief examples:
We can use bind() for events like onClick where you dont know when they will be
fired but you know the desired context.
Object literal :
let userDetails = {
name: "Saikrishna",
city: "Hyderabad"
}
Object constructor :
Object.Create() :
This is used when we want to inherit properties from an existing object while
creating a new object.
let animal = {
name: "Animal name"
}
Object.assign() :
This is used when we want to include properties from multiple other objects
into new object we are creating.
let lesson = {
lessonName: "Data structures"
};
let teacher= {
let data = {
name: "Sai",
lang: "English"
};
Object.keys(data) // ["name","lang"]
Object.values(data) // ["Sai","english"]
Object.entries(data) // [["name","Sai"],["lang","English"]]
Will make the object immutable ( prevents the addition of new propeties
and prevents modification of existing properties)
Object.freeze(data);
data.a= 20;
data.c = 30;
console.log(data)
output: {
a: 10
}
Object.Seal():
Will prevent the addition of new properties but we can modify existing
properties.
let data = {
a : 10
};
Object.seal(data);
data.a = 20;
data.c = 30;
console.log(data)
Output:
data: {
a: 20
}
data.forEach((item,i)=>{
console.log(item,i)
})
Array.prototype.forEach((callback)=>{
for(let i=0;i<=this.length-1;i++){
callback(this[i],i)
}
})
Array.prototype.map=((callback)=>{
let temp = [];
for(let i=0;i<=this.length-1;i++){
console.log(output)
ref: https://dev.to/umerjaved178/polyfills-for-foreach-map-filter-reduce-in-
javascript-1h13
https://www.tutorialsteacher.com/javascript/prototype-in-javascript
function Student(){
this.name = "Saikrishna",
this.exp= "8"
}
Student.prototype.company = "Hexagon"
console.log(std1);
console.log(std2)
They are defined by using function* and it contains one or more yield
expressions.
The main method of generator is next(). when called, it runs the execution until
the nearest yield.
https://javascript.info/generators
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
return 4
}
functions which are executed immediately once they are mounted to the stack
is called iife.
They does not require any explicit call to invoke the function.
https://www.geeksforgeeks.org/immediately-invoked-function-expressions-
iife-in-javascript/
https://www.tutorialsteacher.com/javascript/immediately-invoked-function-
expression-iife
(function(){
console.log("2222")
})()
cors works by adding specific http headers to control which origins have
access to the resources and under what conditions.
https://dev.to/lydiahallie/cs-visualized-cors-5b8h
Typescript is the superset of javascript and has all the object oriented
features.
Authorization:
Its the process of verifying what they have access to. What files and data
user has access to.
👉 Interview Tip: For this question, learn jwt token mechanism and tell that you
have implemented this in your project. This helps a lot.This kills atleast 3-4 min of
interview time 😉
https://www.youtube.com/watch?v=7Q17ubqLfaM
Undefined:
means the variable has been declared but not assigned any value yet.
console.log(newArr) // [2,3]
Splice:
console.log(arr); // [1,2,8,9,6,10]
console.log(newArr); // [3,4,5,0]
setTimeOut(function(){
console.log("Prints Hello after 2 seconds")
},2000);
👉 Interview Tip: Most asked in output based and problem solving so learn
syntax more. Practice some examples.
setInterval(function(){
console.log("Prints Hello after every 2 seconds");
},2000);
Will wait for all of the promises to resolve or any one of the promise
reject.
Promise.allSettled:
Will wait for all the promises to settle (either fulfilled or rejected).
Promise.any:
Will return if any one of the promise fulfills or rejects when all the
promises are rejected.
Promise.race:
https://medium.com/@log2jeet24/javascript-different-types-of-promise-
object-methods-to-handle-the-asynchronous-call-fc93d1506574
👉 Interview Tip: practice some examples on this concepts. This is a practical
question. You can expect some scenario based questions from interviewer on
this concept so prepare well from above link
Each and every function in javascript has access to its outer lexical
environment means access to the variables and functions present in the
environments of its parents
function Outer(){
var a = 10;
function Inner(){
console.log(a);
}
return Inner;
}
Usecases:
setTimeOut
function Print(){
console.log("Print method");
}
function Hello(Print){
console.log("Hello method");
Print();
}
Hello(Print);
Output:
Hello method
Print method
Advantages:
Abstraction
Code reusability
Encapsulation
Ref: https://developer.mozilla.org/en-
US/docs/Web/API/Web_Storage_API#concepts_and_usage
SessionStorage:
𝟏. 𝐈 𝐜𝐫𝐞𝐚𝐭𝐞𝐝 𝐚 𝐥𝐨𝐜𝐚𝐥𝐬𝐭𝐨𝐫𝐚𝐠𝐞 𝐚𝐧𝐝 𝐜𝐥𝐨𝐬𝐞𝐝 𝐭𝐡𝐞 𝐛𝐫𝐨𝐰𝐬𝐞𝐫 𝐚𝐧𝐝 𝐫𝐞𝐩𝐨𝐞𝐧𝐞𝐝 𝐢𝐭. 𝐖𝐢𝐥𝐥 𝐥𝐨𝐜𝐚𝐥 𝐬𝐭𝐨𝐫𝐚𝐠𝐞
𝐝𝐚𝐭𝐚 𝐩𝐞𝐫𝐬𝐢𝐬𝐭𝐬 ?
Yes local storage data persists even when i close and reopen the browser
𝟐. 𝐈 𝐰𝐚𝐧𝐭 𝐭𝐨 𝐚𝐜𝐜𝐞𝐬𝐬 𝐋𝐨𝐜𝐚𝐥 𝐬𝐭𝐨𝐫𝐚𝐠𝐞 𝐝𝐚𝐭𝐚 𝐢𝐧 𝐚𝐧𝐨𝐭𝐡𝐞𝐫 𝐭𝐚𝐛 𝐨𝐟 𝐬𝐚𝐦𝐞 𝐛𝐫𝐨𝐰𝐬𝐞𝐫 𝐢𝐬 𝐢𝐭 𝐩𝐨𝐬𝐬𝐢𝐛𝐥𝐞 ?
Yes we can access local storage data in another tab as well.
𝟑. 𝐈 𝐫𝐞𝐥𝐨𝐚𝐝𝐞𝐝 𝐭𝐡𝐞 𝐩𝐚𝐠𝐞 𝐚𝐟𝐭𝐞𝐫 𝐜𝐫𝐞𝐚𝐭𝐢𝐧𝐠 𝐥𝐨𝐜𝐚𝐥 𝐬𝐭𝐨𝐫𝐚𝐠𝐞. 𝐖𝐢𝐥𝐥 𝐢𝐭 𝐩𝐞𝐫𝐬𝐢𝐬𝐭𝐬 ?
Yes local storage data persists on page reload.
𝟒. 𝐈𝐟 𝐢 𝐨𝐩𝐞𝐧 𝐦𝐮𝐥𝐭𝐢𝐩𝐥𝐞 𝐭𝐚𝐛𝐬 𝐰𝐢𝐭𝐡 𝐬𝐚𝐦𝐞 𝐮𝐫𝐥 𝐡𝐨𝐰 𝐥𝐨𝐜𝐚𝐥 𝐬𝐭𝐨𝐫𝐚𝐠𝐞 𝐛𝐞𝐡𝐚𝐯𝐞𝐬 ?
I can access localstorage data in multiple tabs if its same url
𝟏𝟎. 𝐈 𝐰𝐢𝐥𝐥 𝐭𝐫𝐲 𝐭𝐨 𝐬𝐭𝐨𝐫𝐞 𝐥𝐞𝐭𝐬 𝐬𝐚𝐲 𝐚𝐧 𝐢𝐦𝐚𝐠𝐞 𝐨𝐟 𝐬𝐢𝐳𝐞 𝐦𝐨𝐫𝐞 𝐭𝐡𝐚𝐧 𝟓𝐦𝐛 𝐢𝐧 𝐥𝐨𝐜𝐚𝐥𝐬𝐭𝐨𝐫𝐚𝐠𝐞 𝐭𝐡𝐞𝐧
𝐰𝐡𝐚𝐭 𝐡𝐚𝐩𝐩𝐞𝐧𝐬 ?
It will throw QuotaExceededException if it exceeds the limit.
𝟏𝟏. 𝐖𝐡𝐚𝐭 𝐈𝐟 𝐈 𝐭𝐮𝐫𝐧 𝐨𝐟𝐟 𝐦𝐲 𝐥𝐚𝐩𝐭𝐨𝐩 𝐚𝐧𝐝 𝐫𝐞𝐨𝐩𝐞𝐧 𝐭𝐡𝐞 𝐛𝐫𝐨𝐰𝐬𝐞𝐫, 𝐰𝐢𝐥𝐥 𝐥𝐨𝐜𝐚𝐥 𝐬𝐭𝐨𝐫𝐚𝐠𝐞 𝐝𝐚𝐭𝐚
𝐩𝐞𝐫𝐬𝐢𝐬𝐭𝐬 ?
Yes localstorage data still persists even if i shutdown my laptop and reopen
the browser
Cookies are stored as key value pairs and hold 4kb of data.
When user logins to the application, server uses the set-cookie http
header in the response to set a cookie with a unique session identifier.
Next time when user makes the api requests, cookie will be sent in the http
header by using which server will identify who the user is.
Eg:
document.cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00
UTC; path=/";
Ref: https://www.w3schools.com/js/js_cookies.asp
𝐟𝐮𝐧𝐜𝐭𝐢𝐨𝐧 𝐱(){
𝐜𝐨𝐧𝐬𝐨𝐥𝐞.𝐥𝐨𝐠(𝐭𝐡𝐢𝐬)
}
𝐟𝐮𝐧𝐜𝐭𝐢𝐨𝐧 𝐱(){
𝐜𝐨𝐧𝐬𝐨𝐥𝐞.𝐥𝐨𝐠(𝐭𝐡𝐢𝐬)
}
𝐰𝐢𝐧𝐝𝐨𝐰.𝐱()
𝐥𝐞𝐭 𝐨𝐛𝐣 = {
𝐱:”𝐇𝐞𝐥𝐥𝐨”,
𝐲: 𝐟𝐮𝐧𝐜𝐭𝐢𝐨𝐧(){
𝐜𝐨𝐧𝐬𝐨𝐥𝐞.𝐥𝐨𝐠(𝐭𝐡𝐢𝐬.𝐱)
}
}
𝐨𝐛𝐣.𝐲()
It will print Hello. Because, When ever we are inside the method, the value
of this keyword is the object where this method is present.
𝟕. 𝐖𝐡𝐚𝐭 𝐰𝐢𝐥𝐥 𝐛𝐞 𝐭𝐡𝐞 𝐭𝐡𝐢𝐬 𝐯𝐚𝐥𝐮𝐞 𝐢𝐟 𝐢𝐭'𝐬 𝐥𝐨𝐠𝐠𝐞𝐝 𝐢𝐧𝐬𝐢𝐝𝐞 𝐚𝐫𝐫𝐨𝐰 𝐟𝐮𝐧𝐜𝐭𝐢𝐨𝐧 ?
𝐥𝐞𝐭 𝐨𝐛𝐣 = {
𝐱:”𝐇𝐞𝐥𝐥𝐨”,
𝐲: ()=>{
𝐜𝐨𝐧𝐬𝐨𝐥𝐞.𝐥𝐨𝐠(𝐭𝐡𝐢𝐬)
𝐨𝐛𝐣.𝐲()
It will print window object.Because, Arrow function does not have their own
this binding. they take the this value of their lexical environment where they
are enclosed.
𝟖.𝐖𝐡𝐚𝐭 𝐰𝐢𝐥𝐥 𝐛𝐞 𝐭𝐡𝐢𝐬 𝐯𝐚𝐥𝐮𝐞 𝐢𝐟 𝐢 𝐮𝐬𝐞 𝐢𝐧 𝐛𝐮𝐭𝐭𝐨𝐧 𝐞𝐥𝐞𝐦𝐞𝐧𝐭
<𝐛𝐮𝐭𝐭𝐨𝐧 𝐨𝐧𝐜𝐥𝐢𝐜𝐤="𝐚𝐥𝐞𝐫𝐭(𝐭𝐡𝐢𝐬)">𝐜𝐥𝐢𝐜𝐤</𝐛𝐮𝐭𝐭𝐨𝐧>
axios.interceptors.request.use((config)=>{
if(longUrls.include(url)){
config.timeout = 1000;
}
return config;
}
axios.interceptors.response.use((response)=>{
return response;
})
console.log(eval("1 + 2")); // 3
https://www.linkedin.com/posts/saikrishnanangunuri_javascript-
javascriptdeveloper-reactjs-activity-7211747675635900416-h9IB?
utm_source=share&utm_medium=member_desktop
(Give above post example )
shallowCopy[2][0] = 100;
console.log(originalArray); // Output: [1, 2, [100, 4]]
Deep copy:
A deep copy creates a new object or array that has its own copies of
the properties of the original object.
using lodash:
let array = _.cloneDeep(originalArray)
These variables does not exist in the program and they are not
declared.
undefined:
These variables are declared in the program but are not assigned any
value.
<!DOCTYPE html>
<html>
<script>
document.getElementById('div1').addEventListener(
'click', function() {
console.log('Div 1 clicked');
});
document.getElementById('div2').addEventListener(
'click', function() {
console.log('Div 2 clicked');
});
document.getElementById('button1').addEventListener(
'click', function(event) {
console.log('Button clicked');
// To stop the event from bubbling up
event.stopPropagation();
});
</script>
</body>
</html>
You can enable event capturing by passing true as the third argument to
addEventListener .
<!DOCTYPE html>
<html>
<head>
<title>Event Capturing</title>
</head>
<body>
<div id="div1" style="padding: 50px;
border: 1px solid black;">
Div 1
<div id="div2" style="padding: 50px;
border: 1px solid red;">
Div 2
<button id="button1">Click Me</button>
</div>
</div>
<script>
document.getElementById('div1').addEventListener(
'click', function() {
console.log('Div 1 clicked');
}, true);
document.getElementById('div2').addEventListener(
'click', function() {
document.getElementById('button1').addEventListener(
'click', function(event) {
console.log('Button clicked');
// To stop the event from propagating further
// event.stopPropagation();
}, true);
</script>
</body>
</html>
shift(): removes the first element at the beginning and shifts all the
elements to lower index.
unshift(): adds new element at beginning and moves other elements one
index further.
flat(): creates a new array with all the sub array elements
Ref: https://www.w3schools.com/js/js_array_methods.asp
every(): will check if all the elements of the array satisfies the specified
condition. it return true if all the elements satisfies the condition, else
returns false.
function x(){
data() // This method is not exists.
}
try {
null.f();
} catch (e) {
console.error(e);
// TypeError: Cannot read property 'f' of null
}
Range errors: These errors occurs when the value is not present in
allowed range.
try {
new Array(-1);
} catch (e) {
console.error(e);
// RangeError: Invalid array length
}
try {
eval('eval("invalid code")');
} catch (e) {
console.error(e);
// EvalError (in some older JavaScript versions)
}
URI errors: These erros occurs when wrong characters used in URI
functions
Advantages:
let package = {
version: "2.0",
};
let application = Object.create(package, {
name: { value: "game" },
}); // inherited from package
console.log(application);
console.log(Object.getPrototypeOf(application));
Ref: https://www.scaler.com/topics/javascript/prototype-inheritance-in-
javascript/
ref: https://apidog.com/blog/axios-vs-fetch/
fetch:
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok'
+ response.statusText);
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error(`There has been a problem with
your fetch operation:`, error);
});
axios:
axios.get(url)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(`There has been a problem
with your axios operation:`, error);
});
SOLID:
Arrow functions will solve the common pain points of this binding in
traditional funtional expressions. Arrow functions does not have their own
this. It will take the this value from the parent’s scope (i.e., code that
contains the arrow function). For example, look at the setTimeout function
below.
// ES5
var obj = {
id: 42,
counter: function counter() {
setTimeout(function() {
console.log(this.id);
}.bind(this), 1000);
}
};
obj.counter(); // 42
let count = 0;
const intervalId = setInterval(() => {
console.log(count++);
This code will print the numbers 0 to 5 with a one-second delay between each
number. After printing 5, the clearInterval method will be called, and the interval
will stop.
// worker.js
// main.js
Example: "^1.2.3"
This means that the package manager will install any version from
1.2.3 to less than 2.0.0 .
It will install newer patch versions (e.g., 1.2.4 , 1.2.5 ) and minor
versions (e.g., 1.3.0 , 1.4.0 ), but not major versions (e.g., 2.0.0 ).
Tilde (~)
The tilde ( ~ ) allows updates to the most recent patch version (x.x.1), but it
will not allow updates to the minor or major versions.
Example: "~1.2.3"
This means that the package manager will install any version from
1.2.3 to less than 1.3.0 .
It will install newer patch versions (e.g., 1.2.4 , 1.2.5 ), but not new
minor versions (e.g., 1.3.0 ).
// or
// Add a class
element.classList.add("newClass");
Explaination:
Now expression becomes “5”+ “7” this performs string concatenation and
results in “57”.
const a = 1<2<3;
const b = 1>2>3;
console.log(a,b) //true,false
Output:
true, false
const p = { k: 1, l: 2 };
const q = { k: 1, l: 2 };
let isEqual = p==q;
let isStartEqual = p=== q;
console.log(isEqual, isStartEqual)
OutPut:
False,False
isStartEqual will also be false for the same reason. The === operator
checks for strict equality, meaning it not only compares values but also
ensures that the objects being compared reference the exact same
memory location.
a) 2+2 = ?
b) "2"+"2" = ?
c) 2+2-2 = ?
d) "2"+"2"-"2" = ? (tricky remember this)
e) 4+"2"+2+4+"25"+2+2 ?
a) 2+2 = ?
console.log(2 + 2); // Output: 4
b) "2"+"2" = ?
console.log("2" + "2");
// Output: "22" (string concatenation)
c) 2+2-2 = ?
console.log(2 + 2 - 2); // Output: 2
d) "2"+"2"-"2" = ?
console.log("2" + "2" - "2");
// Output: 20 (string "22" is converted
to a number, then subtracted by the number 2)
e) 4+"2"+2+4+"25"+2+2
console.log(4+"2"+2+4+"25"+2+2);
// "42242522"
let a = 'jscafe'
a[0] = 'c'
console.log(a)
Output:
“jscafe”
var x=10;
function foo(){
var x = 5;
console.log(x)
}
foo();
console.log(x)
Output: 5 and 10
In JavaScript, this code demonstrates variable scoping. When you declare a
variable inside a function using the var keyword, it creates a new variable
scoped to that function, which may shadow a variable with the same name in
an outer scope. Here's what happens step by step:
1. var x = 10; : Declares a global variable x and initializes it with the value 10 .
it with the value 5 . This x is scoped to the function foo and is different
from the global x .
console.log("Start");
setTimeout(() => {
console.log("Timeout");
});
Promise.resolve().then(() => console.log("Promise"));
console.log("End");
Output:
Start, End,Promise,Timeout.
function x(){
for(var i=1;i<=5;i++){
x();
function x() {
function closur(x) {
// Set a timeout to log value of x after x seconds
setTimeout(() => {
console.log(x);
}, x * 1000);
};
// Loop from 1 to 5
for (var i = 1; i <= 5; i++) {
// Call the closure function with current value of i
closur(i);
}
}
3. For each iteration of the loop, the inner function closur is called with the
current value of i .
Each call to closur(i) creates a new closure that captures the current value of i
1 (after 1 second)
2 (after 2 seconds)
3 (after 3 seconds)
4 (after 4 seconds)
5 (after 5 seconds)
This happens because each iteration of the loop calls closur with a different
value of i , and each setTimeout inside closur is set to log that value after i
seconds.
function x(){
let a = 10;
function d(){
console.log(a);
}
a = 500;
return d;
}
2. : Declares a variable
let a = 10; a inside the function x and initializes it with
the value 10 .
3. function d() { ... } : Defines a nested function named d inside the function x .
When you run this code, it will log the value of a at the time of executing d ,
which is 500 , because d retains access to the variable a even after x has
finished executing. This behavior is possible due to closure, which allows
inner functions to access variables from their outer scope even after the outer
function has completed execution.
getData1()
getData();
Output:
Explanation:
In JavaScript, function declarations are hoisted to the top of their scope, while
variable declarations using var are also hoisted but initialized with undefined .
Here's what happens in your code:
getData is declared using var , so it's also hoisted to the top but
initialized with undefined .
It will throw an error because getData is undefined , and you cannot call
undefined as a function.
Therefore, if you try to run the code as is, you'll encounter an error when
attempting to call getData() .
If you want to avoid this error, you should either define getData before calling it
or use a function declaration instead of a variable declaration for getData .
Here's how you can do it:
Modification needed for code:
function func() {
try {
console.log(1)
return
} catch (e) {
console.log(2)
} finally {
console.log(3)
}
console.log(4)
}
Output: 1 & 3
Since return is encountered within the try block, the control exits the function
immediately after console.log(1) . The catch block is skipped because there are no
errors, and the code in the finally block is executed regardless of whether an
error occurred or not.
So, when you run this code, it will only print 1 and 3 to the console.
Explanation:
Many of you might have thought the output to be 1,2,3,4,5,6,7. But “break”
statement works only loops like for, while, do…while and not for map(),
let a = true;
setTimeout(() => {
a = false;
}, 2000)
while(a) {
console.log(' -- inside whilee -- ');
}
Solution: https://medium.com/@iamyashkhandelwal/5-output-based-
interview-questions-in-javascript-b64a707f34d2
This code snippet creates an infinite loop. Let's break it down:
2. setTimeout(() => { a = false; }, 2000) : This sets up a timer to execute a function after
2000 milliseconds (2 seconds). The function assigned to setTimeout will set
the value of a to false after the timeout.
3. while(a) { console.log(' -- inside whilee -- '); } : This is a while loop that continues to
execute as long as the condition a is true . Inside the loop, it prints ' -- inside
whilee -- ' .
The issue here is that the while loop runs indefinitely because there's no
opportunity for the JavaScript event loop to process the setTimeout callback
console.log(2);
console.log(5);
This code demonstrates the event loop in JavaScript. Here's the breakdown of
what happens:
Promise. The executor function inside the Promise logs 3 to the console
and then resolves the Promise immediately with res() . The then() method is
chained to the Promise, so once it's resolved, it logs 4 to the console.
2
3
5
4
1
Here's why:
Once the current synchronous execution is done, the event loop picks up
the resolved Promise and executes its then() callback, logging 4 .
https://medium.com/@iamyashkhandelwal/5-output-based-interview-
questions-in-javascript-b64a707f34d2
console.log("D");
foo();
console.log("E")
Output:
D, A, E, B, C
Explanation:
The main context logs “D” because it is synchronous and executed
immediately.
The foo() function logs "A" to the console since it's synchronous and executed
immediately. await Promise.resolve() : This line awaits the resolution of a
Promise. The Promise.resolve() function returns a resolved Promise
immediately. The control is temporarily returned to the caller function ( foo() ),
allowing other synchronous operations to execute.
Back to the main context: console.log("E") : This line logs "E" to the console
since it's a synchronous operation. The foo()
function is still not fully executed, and it's waiting for the resolution of the
Promise inside it. Inside foo()
(resumed execution): console.log("B") : This line logs "B" to the console since
it's a synchronous operation.
await new Promise(resolve => setTimeout(resolve, 0));
This line awaits the resolution of a Promise returned by the setTimeout
function. Although the delay is set to 0 milliseconds, the setTimeout callback
is pushed into the callback queue, allowing the synchronous code to continue.
Back to the main context: The control is still waiting for the foo() function to
complete.
Inside foo() (resumed execution): The callback from the setTimeout is picked
up from the callback queue, and the promise is resolved. This allows the
execution of the next await .
Output: 3
Let me break it down for you:
3. Finally, the function returns x . Since x was passed as 3 when calling the
function (function(x){ ... })(3) , it returns 3 .
Output: 3 3 3
This might seem counterintuitive at first glance, but it's due to how JavaScript
handles closures and asynchronous execution.
Here's why:
4. The loop checks if i is still less than 3 . Since it's now 3 , the loop exits.
When the timeouts execute after their respective intervals, they access the
variable i from the outer scope. At the time of execution, i is 3 because the
loop has already finished and incremented i to 3 . So, all three timeouts log
3 .
Output: 3
3. Finally, the function returns x . Since x was passed as 3 when calling the
function (function(x){ ... })(3) , it returns 3 .
let c=0;
setTimeout(() => {
clearInterval(id)
},2000)
This JavaScript code sets up an interval that increments the value of c every
200 milliseconds and logs its value to the console. After 2 seconds (2000
milliseconds), it clears the interval.
Here's what each part does:
This code essentially logs the values of c at 200 milliseconds intervals until 2
seconds have passed, at which point it stops logging.
function getName1(){
console.log(this.name);
}
Object.prototype.getName2 = () =>{
console.log(this.name)
}
let personObj = {
name:"Tony",
print:getName1
}
personObj.print();
personObj.getName2();
function getName1(){
console.log(this.name);
}
Object.prototype.getName2 = () =>{
console.log(Object.getPrototypeOf(this).name);
}
let personObj = {
name:"Tony",
print:getName1
}
personObj.print();
Object.prototype.name="Steve";
personObj.getName2();
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
}
}
test();
2. Inside test :
function job(){
return new Promise((resolve,reject)=>{
reject()
})
}
promise.then(()=>{
console.log("1111111111")
}).then(()=>{
console.log("22222222222")
In this code, a Promise is created with the job function. Inside the job
1. The first then method is chained to the promise , but it is not executed
because the Promise is rejected, so the execution jumps to the catch
method.
2. The catch method catches the rejection of the Promise and executes its
callback, logging "3333333333".
3. Another then method is chained after the catch method. Despite the
previous rejection, this then method will still be executed because it's part
of the Promise chain, regardless of previous rejections or resolutions. It
logs "4444444444".
So, when you run this code, you'll see the following output:
3333333333
4444444444
var a = 1;
function data() {
data();
console.log(a);
Explanation:
var a = 1;
function toTheMoon() {
var a;
/* var has function scope,Hence
it's declaration will be hoisted */
if(!a) {
a = 10;
}
console.log(a);
// 10 precendence will be given to local scoped variable.
}
toTheMoon();
console.log(a); // 1 refers to the `a` defined at the top.
console.log(a == b);
console.log(a === b);
}
guessArray();
In JavaScript, when you compare two arrays using the == or === operators,
you're comparing their references, not their contents. So, even if two arrays
have the same elements, they will not be considered equal unless they refer to
the exact same object in memory.
In your guessArray function, a and b are two separate arrays with the same
elements, but they are distinct objects in memory. Therefore, a == b and a === b
will both return false , indicating that a and b are not the same object.
If you want to compare the contents of the arrays, you'll need to compare
each element individually.
let a = 3;
let b = new Number(3);
let c = 3;
console.log(a == b);
console.log(a === b);
console.log(b === c);
var x = 23;
(function(){
var x = 43;
(function random(){
x++;
console.log(x);
var x = 21;
})();
})();
Solution:
The provided code snippet demonstrates the behavior of variable hoisting and
function scope in JavaScript. Let's analyze the code step-by-step to
understand the output:
var x = 23;
(function(){
var x = 43;
(function random(){
x++;
})();
Breakdown
1. Global Scope:
var x = 23;
(function(){
var x = 43;
// ...
})();
(function random(){
x++;
console.log(x);
var x = 21;
})();
Another function scope is created inside the first IIFE. The function
random is invoked immediately.
Here, variable hoisting comes into play. The declaration var x = 21; is
hoisted to the top of the function random , but not its initialization. Thus,
the code is interpreted as:
Summary
When random function is executed, the following sequence occurs:
Output
Thus, the output of the code is:
28. Can you find is there any security issue in the javascript
code?
To mitigate this security risk, you should properly sanitize or escape the data
before assigning it to innerHTML , or consider using safer alternatives like
textContent or creating DOM elements programmatically.
Here's an example of how you could sanitize the data using a library like
DOMPurify:
By using DOMPurify.sanitize() , you can ensure that any potentially harmful content
is removed or escaped, reducing the risk of XSS attacks. Make sure to include
the DOMPurify library in your project if you choose to use it.
Always remember to validate and sanitize any data that originates from
external sources before inserting it into your DOM.
In the above code, we are using typeof operator. So what is this typeof ?
typeof is an operator in javascript which will return the data type of the
operand which is passed to it
In the above example, Initially typeof 1 will be executed which will return
“number”.
Now the expression will become typeof “number” which will result in
“string”.
x++;
console.log(x);
var x = 21;
Explaination:
In the first line we are using postfix operator. so javascript will perform
type cohercion and tries to convert this undefined into a number.
As a result, value of x will become Nan and in the 2nd line x value ie., Nan
is logged to the console.
const x = [1];
const y = [2];
console.log(x+y);
Explanation:
1. Variable Declaration:
4. String Concatenation:
The + operator then concatenates the strings "1" and "2" , resulting in
the string "12" .
5. Console Output:
When used with arrays, the + operator implicitly converts the arrays to
strings and then concatenates them.
const data = {
name: "sai",
name: "krishna"
}
console.log(data.name);
Output: “krishna”.
Explanation:
In JavaScript, if an object has multiple properties with the same name, the last
one defined in the object will overwrite the previous ones. This behavior
occurs because object properties in JavaScript are treated as key-value pairs,
where keys must be unique.
let x = 10+2*3
console.log(x);
Output: 16
const x = [1,2,3];
const y = [1,3,4];
console.log(x+y);
Output: “1,2,31,3,4”;
Video Explaination: https://www.instagram.com/p/DHoMoC0ii_x/
Explaination:
Here we are defining two arrays:
x is [1, 2, 3]
y is [1, 3, 4]
When you use the + operator with arrays, JavaScript converts each array to a
string. Under the hood, this conversion happens by calling the toString() method
on the arrays. For example:
Then, the + operator concatenates these two strings together. So the result of
x+y is the string:
Finally, console.log prints "1,2,31,3,4" this string to the console.
console.log(+true);
console.log(!"sai");
Output: 1,false
Video Explaination:https://www.instagram.com/p/DHlWUMaChl9/
Explaination:
console.log(+true);
The unary plus operator ( + ) converts its operand into a number.
true is converted to 1 .
console.log(!"sai");
The logical NOT operator ( ! ) converts its operand to a boolean and then
negates it.
In summary:
+true becomes 1 .
Output: “”,”1”,”1abc”
Video Explaination: https://www.instagram.com/p/DHixQfaiwKE/
Explaination:
When you use the + operator with arrays, JavaScript first converts the arrays
into strings using their toString() method:
[] + []
An empty array ( [] ) converts to an empty string ( "" ). So, "" + "" results in
an empty string.
[1] + []
The array [1] converts to "1" , and [] converts to "" . So, "1" + "" results in
"1" .
[1] + "abc"
Again, [1] converts to "1" . Then "1" + "abc" concatenates to give "1abc" .
In summary, the arrays are turned into strings before they are concatenated.
function getAge(...args){
console.log(typeof args)
}
getAge(21)
Output: “object”
Video Explaination: https://www.instagram.com/p/DHdo1CLi4ud/
2. typeof Behavior:
In JavaScript, arrays are technically a type of object. When you
use typeof on an array (like args ), it returns "object" , not "array" .
const obj = {
a: "one",
b: "two",
a: "three"
}
console.log(obj);
Output:
{
a: "three",
b: "two"
}
const obj = {
a: "one", // overwritten by the next 'a'
b: "two",
a: "three" // this is the final value of 'a'
};
var z = 1, y = z = typeof y;
console.log(y);
Output: "undefined"
Video Explaination: https://www.instagram.com/p/DGlAOTsimyX/
Explaination:
The output of the code will be "undefined" . Here's why:
Step-by-Step Breakdown:
1. Variable Hoisting:
Variables z and y are declared (due to var hoisting) but not yet initialized.
At this stage:
y is undefined (temporarily).
2. Initial Assignments:
y returns "undefined" .
4. Final Result:
Key Takeaways:
Hoisting: Variables declared with var are hoisted and initialized
to undefined before assignment.
Explanation:
Key Rules:
|| (OR): Stops at the first truthy value.
If all values are checked (e.g., all truthy for || or all falsy for && ), the last
value is returned.
1. Array Destructuring:
...y uses the rest operator ( ... ) to collect the remaining elements into
a new array y .
2. Result:
x → 1
y → [2, 3, 4, 5]
Key Rules:
The rest operator ( ... ) must always be the last element in destructuring.
1. Code Breakdown:
3. Concatenation:
Key Takeaway:
The unary + operator converts values to numbers.
1. [1].push(2) :
But push() returns the new length of the array (not the array itself).
2. newlist.push(3) :
Key Takeaway:
push() returns the array’s length, not the array itself. Always work directly with
the array variable.
console.log(0 || 1);
console.log(1 || 2);
1 , 1 , 0 , 2
1. console.log(0 || 1);
Logical OR ( || ) returns the first truthy value.
1 is truthy → return 1 .
Output: 1
2. console.log(1 || 2);
Logical OR ( || ) stops at the first truthy value.
2 is truthy → return 2 .
Output: 2
&& (AND):
console.log(data());
var data = function(){
return "1";
}
2. Execution Order:
Key Fix:
Use a function declaration (which is fully hoisted):
Comparison:
Key Takeaway:
Function expressions assigned to variables ( var x = function(){} ) are not hoisted as
callable functions. Function declarations ( function x(){} ) are fully hoisted.
1. Initial Array:
2. Assigning to Index 5:
arr[5] = 6;
Indexes 3 and 4 become "empty slots" (they are not initialized with any
value).
3. Array Length:
Final Output:
console.log(arr.length); // 6
Key Takeaways:
Arrays in JavaScript are dynamic and expand when you assign values to
non-existing indexes.
Empty slots are not the same as undefined – they are gaps in the array.
const obj = {
a:1
}
obj.a = 2;
console.log(obj);
1. Object Creation:
const obj = { a: 1 };
obj.a = 2;
3. Final Output:
console.log(obj); // { a: 2 }
let x = {
a: undefined,
b: null
}
console.log(JSON.stringify(x))
1. Object x :
let x = {
a: undefined,
b: null
};
2. JSON.stringify() Behavior:
3. Result:
console.log(JSON.stringify(x)); // {"b":null}
Key Takeaways:
JSON.stringify() ignores properties with undefined values.
console.log(true + 1);
console.log(true+"1");
2 and "true1"
1. console.log(true + 1);
Boolean Conversion: JavaScript converts true to its numeric equivalent:
true → 1
Addition:
1 (true) + 1 = 2
Output: 2
2. console.log(true + "1");
String Concatenation: When + is used with a string ( "1" ), JavaScript
converts both values to strings.
Concatenation:
Output: "true1"
Key Rules:
+ with numbers: Booleans convert to numbers ( true → 1 , false → 0 ).
Explaination:
The output will be undefined .
Key Takeaway:
Primitive strings (like "hello" ) cannot hold custom properties. Use an object
(e.g., {} ) if you need to add properties.
return uniqueArr;
};
removeDuplicatesWay1([1, 2, 1, 3, 4, 2, 2, 1, 5, 6]);
function removeDuplicatesWay2(arr) {
/* Use the Set object to remove duplicates. This works
because Sets only store unique values */
return Array.from(new Set(arr));
// return [...new Set(arr)] => another way
}
removeDuplicates([1, 2, 1, 3, 4, 2, 2, 1, 5, 6]);
function findEvenNumbers(arr) {
const result = [];
return result;
}
// Example usage:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8,-8,19, 9, 10];
console.log("Even numbers:", findEvenNumbers(numbers));
console.log(checkPallindrome("madam"));
console.log(findFactorial(4));
console.log(longestWord);
};
function findMax(arr) {
if (arr.length === 0) {
return undefined;
// Handle empty array case
}
return max;
}
// Example usage:
const numbers = [1, 6, -33, 9, 4, 8, 2];
console.log("Maximum number is:", findMax(numbers));
function isPrime(number) {
if (number <= 1) {
return false;
// 1 and numbers less than 1 are not prime
}
return true;
// If not divisible by any number, it's prime
}
// Example usage:
function findSmallestWord() {
const sentence = "Find the smallest word";
const words = sentence.split(' ');
let smallestWord = words[0];
If the input array is empty or contains less than 3 numbers then return 0.
The input array will contain only numbers.
function fibonacciSequence(numTerms) {
if (numTerms <= 0) {
return [];
} else if (numTerms === 1) {
return [0];
}
return sequence;
}
// Example usage:
const numTerms = 10;
const fibonacciSeries = fibonacciSequence(numTerms);
console.log(fibonacciSeries);
// Output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
console.log(maxCount);
};
let i = 1;
let j=1;
let array1 = arr1[0];
let array2 = arr2[0];
while(array1 || array2){
}
console.log(mergedArray)
sortedData([1,3,4,5],[2,6,8,9])
14. Create a function which will accepts two arrays arr1 and
arr2. The function should return true if every value in arr1 has
its corresponding value squared in array2. The frequency of
values must be same. (Effecient)
=============
[1,2,3],[4,1,9] ==> true
function isSameFrequency(arr1,arr2){
let arrFreq1={};
let arrFreq2={};
console.log(isSameFrequency([1,2,5],[25,4,1]))
function isStringCreated(str1,str2){
if(str1.length !== str2.length) return false
let freq = {};
console.log(isStringCreated('anagram','nagaram'))
function getUniqueArr(array){
const uniqueArr = [];
const seen = {};
for(let i=0; i<=array.length-1;i++){
const currentItem = array[i].name;
if(!seen[currentItem]){
uniqueArr.push(array[i]);
seen[currentItem] = true;
}
}
return uniqueArr;
}
function findLargestElement(arr) {
let max = Number.NEGATIVE_INFINITY;
// Initialize max to smallest possible number
return max;
}
function countCharacters(str) {
// Object to store character counts
const charCount = {};
const len = str.length;
return charCount;
}
// Example usage:
const result = countCharacters("helaalo");
console.log(result);
// Output: { h: 1, e: 1, l: 2, o: 1 }
function quickSort(arr) {
// Check if the array is empty or has only one element
if (arr.length <= 1) {
return arr;
}
// Example usage:
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
// Example usage
reverseWords("ChatGPT is awesome");
//"awesome is ChatGPT"
function reverseWords(sentence) {
// Split the sentence into words
let words = [];
let wordStart = 0;
for (let i = 0; i < sentence.length; i++) {
if (sentence[i] === ' ') {
words.unshift(sentence.substring(wordStart, i));
wordStart = i + 1;
} else if (i === sentence.length - 1) {
words.unshift(sentence.substring(wordStart,i+1));
}
}
// Example usage
const sentence = "ChatGPT is awesome";
console.log(reverseWords(sentence));
// Output: "awesome is ChatGPT"
while (stack.length) {
const next = stack.pop();
if (Array.isArray(next)) {
stack.push(...next);
} else {
result.push(next);
}
}
return result.reverse();
// Reverse the result to maintain original order
}
// Example usage:
const nestedArray = [1, [2, [3, 4], [7,5]], 6];
const flattenedArray = flattenArray(nestedArray);
console.log(flattenedArray);
// Output: [1, 2, 3, 4, 5, 6]
return result;
}
24. Given an array, return an array where the each value is the
product of the next two items: E.g. [3, 4, 5] -> [20, 15, 12]
function productOfNextTwo(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
if (i < arr.length - 1) {
result.push(arr[i + 1] * arr[i + 2]);
} else {
result.push(arr[0] * arr[1]);
}
}
return result;
}
// Example usage:
const inputArray = [3, 4, 5];
function findSecondLargest(arr) {
if (arr.length < 2) {
throw new Error(`Array must contain
at least two elements.`);
}
return secondLargest;
}
// Example usage:
return pairs;
}
O/P: 1a2b3c4d2e1a
function encodeString(input) {
if (input.length === 0) return "";
return result;
}
1. What is React?
React is an opensource component based JavaScript library which is used
to develop interactive user interfaces.
Virtual dom
3. What is JSX ?
JSX means javascript xml. It allows the user to write the code similar to
html in their javascript files.
This jsx will be transpiled into javascript that interacts with the browser
when the application is built.
4. What is DOM ?
Now this virtual dom is compared with the original dom and creates a
changeset which will be applied on the real dom.
So instead of updating the entire realdom, it will be updated with only the
things that have actually been changed.
Rendering Efficiency:
Virtual DOM: Updates to the Virtual DOM are typically faster because
they occur in memory and are not directly reflected in the browser.
function User() {
const [message, setMessage] = useState("Welcome React");
return (
this.state = {
message: "Welcome to React world",
};
}
render() {
return (
<div>
<h1>{this.state.message}</h1>
</div>
);
}
}
They are used to send data from parent component to child component.
Props are immutable, so they cannot be modified directly within the child
component.
Example:
// ParentComponent.js
import React from 'react';
import ChildComponent from './ChildComponent';
function ParentComponent() {
const name = "John";
return (
<div>
<h1>Parent Component</h1>
<ChildComponent name={name} />
</div>
);
}
// ChildComponent.js
import React from 'react';
function ChildComponent(props) {
return (
<div>
<h2>Child Component</h2>
State is used to hold the data of a component whereas props are used to
send data from one component to another component.
Reduced maintainability:
Prop drilling can also make code less maintainable. This is because if a
prop needs to be changed, the change needs to be propagated through all
of the components that use it. This can be a time-consuming and error-
prone process.
Prop drilling can also increase the risk of errors. This is because it can be
difficult to keep track of which components are using which props, and it
can be easy to forget to pass a prop down to a component that needs
it. This can lead to errors in the application.
Performance overhead:
Prop drilling can also have a performance overhead. This is because every
time a prop is passed down to a component, the component needs to re-
render. This can be a significant performance overhead in large
applications with many components.
We can avoid props drilling using context api or Redux or by using any state
management libraries.
Example :
useEffect(()=>{
console.log("Called on initial mount only once")
},[])
This will be called whenever dependency value changes (here Eg: isFeature or
content).
useEffect(()=>{
return ()=>{
console.log(`Any cleanup activities
or unsubscribing etc here`)
}
})
mounting
updating
unmounting
Mounting:
1. Constructor:
This is called right before rendering the elements into the dom.
Its a natural place to set the state object based on the initial props.
getDerivedStateFromProps(props,state){
return { favColor: props.favColor }
}
3. render():
It contains all the html elements and is method that actually outputs
the html to the dom.
4. ComponentDidMount():
Updating phase:
2. ShouldComponentUpdate:
This will return boolean value that specifies whether react should
continue with the rendering or not. default is true.
shouldComponentUpdate(){
return true/false
}
It will have access to the props and state before update. means
that even after the update you can check what are the values were
before update.
getSnapshotBeforeUpdate(prevProps,prevState){
console.log(prevProps,prevState)
}
5. ComponentDidUpdate:
Unmounting phase:
In this phase the component will be removed from the dom. here we
can do unsubscribe to some events or destroying the existing dialogs
etc.
1. ComponentWillUnmount:
react will use this to indentify, which elements in the list have been added,
removed or updated.
function MyComponent() {
const items = [
{ id: 1, name: "apple" },
{ id: 2, name: "banana" },
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
Advantage:
Reference: https://react.dev/reference/react/PureComponent
Uncontrolled components:
they are helpful when we want to update the component whith out using
state and props and prevents triggering rerender.
Common useCases:
Media control/Playback
Examples:
1. Managing input focus
function App() {
const inputRef = useRef();
return (
<div>
<input type='text' ref={inputRef} />
<button onClick={focusOnInput}>Click Me</button>
</div>
);
}
function App() {
const audioRef = useRef();
return (
<div>
<audio
ref={audioRef}
type='audio/mp3'
src='https://s3-us-west-2.amazonaws.com/keyboard-32-12.mp3'
></audio>
<button onClick={playAudio}>Play Audio</button>
<button onClick={pauseAudio}>Pause Audio</button>
</div>
Reference: https://www.memberstack.com/blog/react-refs
Example:
2. Using the Forward Ref Component: Use this component and pass a ref to
it.
function ParentComponent() {
const inputRef = useRef(null);
return (
<div>
<ChildComponent ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>
static getDerivedStateFromError(error) {
/* Update state so the next render will
show the fallback UI. */
return { hasError: true };
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return this.props.fallback;
}
return this.props.children;
}
}
Then you can wrap a part of your component tree with it:
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
Eg:
Fetch data
https://react.dev/learn/reusing-logic-with-custom-hooks
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
setData(result);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
// Cleanup function
return () => {
// Cleanup logic if needed
};
}, [url]); // Dependency array to watch for changes
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return (
<div>
{data && (
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</div>
);
}
Create context
Create Provider and wrap this provider around root level component and
pass the data.
Data fetching : Sharing fetched data across multiple components that need
to display this data. (for displaying search results when user makes a
search request).
UserContext.js
Step - 2: We need to wrap the root level component with provider and
pass the user Information.
App component:
return (
<div>
<UserProvider value={userinfo}>
<ComponentA/>
</UserProvider>
</div>
);
};
Step - 3: In componentA, We can get the data using useContext and utilize
the user Information.
ComponentA:
=======================================================
// Enabling strict mode for entire App.
=======================================================
=======================================================
// Any part of your app
=======================================================
function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}
32. What are the different ways to pass data from child
component to parent component in react ?
There are 4 common ways to send data from child component to parent
component. They are.,
1. Callback Functions
2. Context API
4. Redux
Virtualization: Implement virtual lists and grids to render only the visible
elements, improving rendering performance for large datasets.
Optimize rendering with keys: Ensure each list item in a mapped array
has a unique and stable key prop to optimize rendering performance. Keys
help React identify which items have changed, been added, or removed,
minimizing unnecessary DOM updates.
CDN Integration: Serve static assets and resources from Content Delivery
Networks (CDNs) to reduce latency and improve reliability.
37. What are the differences between client side and server
side rendering
Initial Load time: csr has slow initial load time as browser needs to
interpret the data and render the page. where as ssr has faster initial load
times as server send pre-rendered html page to the browser.
Seo: Ssr is seo friendly when compared to csr as fully rendered html
content is provided to the search engine crawlers whereas csr needs to
parse javascript heavy content.
Router: It wraps the entire application and provides the routing context for
the application. It contains 2 types of routers,
Browser router and Hash router.
Route: It contains mapping between urlpath and the component. When the
url matches, respective component will be rendered.
Link: is used to create the navigation links which user can click to navigate
to different routes.
switch: is used to render the first matching route among its children. It
ensures only one route is rendered.
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Contact() {
return <h2>Contact</h2>;
}
function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">
Home
</Link>
</li>
<li>
<Link to="/about">
About
</Link>
</li>
<li>
<Link to="/contact">
Contact
</Link>
<Switch>
<Route exact path="/"
component={Home}
/>
<Route path="/about"
component={About}
/>
<Route path="/contact"
component={Contact}
/>
</Switch>
</div>
</Router>
);
}
Ref : https://www.youtube.com/watch?v=wU57kvYOxT4
https://mtg-dev.tech/blog/real-world-example-to-use-uselayouteffect
When an event occurs in the child component (like a button click), call this
function with the data to be passed to the parent.
Parent Component:
function ParentComponent() {
const [dataFromChild, setDataFromChild] = useState('');
return (
<div>
<ChildComponent onData={handleDataFromChild} />
<p>Data from child: {dataFromChild}</p>
</div>
Child Component:
return (
<button onClick={sendDataToParent}>
Send Data to Parent
</button>
);
}
It will not trigger any event by itself whenever the data is updated.
Parent component:
return (
<>
<TextEditor valueRef={valueRef} />
<button onClick={() => {
console.log(valueRef.current)}
}
>Get</button>
</>
);
}
Child component:
// Reducer function
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
};
// Component
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch(
{ type: 'increment' }
)}>Increment</button>
<button onClick={() => dispatch(
{ type: 'decrement' }
)}>Decrement</button>
</div>
);
};
useCounter.js:
return {
counter,
increment,
decrement,
};
};
component.js:
import { useCounter } from './useCounter.js';
return (
return (
<div>
{checkboxes.map((checkbox) => (
<Checkbox
key={checkbox.id}
label={checkbox.label}
checked={checkbox.checked}
onChange={
() => handleCheckboxChange(checkbox.id)
}
/>
))}
<button
onClick={handleSelectAll}
disabled={selectAllDisabled}>
{selectAllDisabled ? 'Deselect All' : 'Select All'}
</button>
<p>Selected: {selectedCount}</p>
<ul>
{selectedCheckboxes.map((checkbox) => (
<li key={checkbox.id}>{checkbox.label}</li>
))}
</ul>
</div>
);
};
Solution:
Create App component and circle component. We will use recursion concept
to achieve this.
App.js:
return (
<div className="nested-circles-container">
App.css/Style.css:
.nested-circles-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
Circle.js:
Circle.css:
.circle-new {
border-radius: 100%;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
}
HOC Pattern
Container/Presentational pattern
https://javascriptpatterns.vercel.app/patterns/react-patterns/render-props
For example, if we wanted to show listings on the landing page, we could use
a container component to fetch the data for the recent listings, and use a
presentational component to actually render this data.
https://javascriptpatterns.vercel.app/patterns/react-patterns/conpres
// ParentComponent.jsx
function ParentComponent() {
const message = "Hello from Parent!";// Data to send
const user = { name: "Alice", age: 30 };
return (
<div>
{/* Pass data as props */}
<ChildComponent text={message} userData={user} isAdmin={false}/>
</div>);
}
// ChildComponent.jsx
function ChildComponent(props) {
return (
<div>
<h1>{props.text}</h1>
In the child component, invoke the prop when needed (e.g., on a button click).
function ParentComponent() {
const handleChildAction = (data) => {
console.log('Method called from child!', data);
};
return (
<div>
<ChildComponent onAction={handleChildAction} />
</div>);
}
// ChildComponent.jsx
import React from 'react';
// ParentComponent.jsx
import React from 'react';
import ChildComponent from './ChildComponent';
render() {
return <ChildComponent onAction={this.handleChildAction} />;
}
}
// ChildComponent.jsx
import React from 'react';
// Array of objects
const countries = [
{ id: 1, name: 'India' },
{ id: 2, name: 'USA' },
{ id: 3, name: 'Canada' },
];
return (
<div>
{/* Dropdown using simple array */}
<select value={selectedFruit} onChange={(e) => setSelectedFruit(e.target.
value)}>
<option value="" disabled>Select Fruit</option>
{fruits.map((fruit, index) => (
<option key={index} value={fruit}>
{fruit}
</option>
))}
</select>
📌 Explanation:
Mapping ( array.map ): Used to loop through the array and render options.
🖥️ Output Example:
Selecting Banana sets selectedFruit to 'Banana' .
2. Lazy load this component in your main application file (e.g., App.jsx )
// App.jsx
import React, { lazy, Suspense } from 'react';
return (
<div>
<inputtype="text"
placeholder="Enter something..."
value={inputValue}
onChange={handleChange}
/>
<inputtype="text"
placeholder="Displayed value..."
Explanation:
useState hook manages the entered value.
The second input displays the entered text, set as readOnly to prevent manual
editing.
This allows you to see the entered text mirrored immediately in another textbox.
if (isAdmin) {
content = <p>Admin Dashboard</p>;
} else {
content = <p>User Dashboard</p>;
}
return <div>{content}</div>;
}
function DebounceExample() {
const [inputValue, setInputValue] = useState('');
const [debouncedValue, setDebouncedValue] = useState('');
useEffect(() => {
// Clear the previous timer if inputValue changes
if (timerRef.current) clearTimeout(timerRef.current);
// Cleanup function
return () => clearTimeout(timerRef.current);
}, [inputValue]);
return (
<div>
<inputtype="text"
value={inputValue}
placeholder="Type something..."
onChange={handleInputChange}
/>
Explanation:
useState: Manages the immediate ( inputValue ) and debounced values
( debouncedValue ).
This technique ensures actions are performed only after the user stops typing for
a short period, optimizing performance and preventing unnecessary function
calls.
useEffect(() => {
setLoading(true);
setError(null);
fetch(apiUrl)
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
})
.then((json) => {
setData(json);
setLoading(false);
})
.catch((err) => {
setError(err.message || "Something went wrong");
setLoading(false);
});
}, [apiUrl]);
return (
<div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
Usage:
Explanation:
Uses useEffect to fetch data when the component mounts or when apiUrl
changes.
const countries = [
{ id: "in", name: "India" },
{ id: "us", name: "USA" },
];
const states = {
in: [
{ id: "mh", name: "Maharashtra" },
{ id: "tg", name: "Telangana" },
],
us: [
{ id: "ca", name: "California" },
{ id: "ny", name: "New York" },
],
};
return (
<div>
<label>
<br />
<label>
State:{" "}
<selectvalue={selectedState}
onChange={handleStateChange}
disabled={!selectedCountry}
>
<option value="">-- Select State --</option>
{selectedCountry &&
states[selectedCountry]?.map((state) => (
<option key={state.id} value={state.id}>
{state.name}
</option>
))}
</select>
</label>
</div>
);
};
How it works:
// Usage
const someHtml = "<p>This is <strong>dynamic</strong> HTML content.</p
>";
Important Notes:
React escapes HTML by default to prevent XSS attacks.
function MyComponent() {
const [items, setItems] = useState([]);
return (
<><button onClick={() => addItem("New item")}>Add Item</button>
<ul>
{items.map((item, idx) => (
<li key={idx}>{item}</li>
))}
</ul>
</>
);
}
Explanation:
Use the updater function form of setItems to get the latest state.
Create a new array with the spread operator [...prevItems, newItem] to add the new
item.
useEffect(() => {
if (shouldFocus && inputRef.current) {
inputRef.current.focus();
}
}, [shouldFocus]);
return (
<inputref={inputRef}
type="text"
disabled={disabled}
placeholder={disabled ? "Disabled" : "Enabled"}
/>
);
}
function Parent() {
const [disabled, setDisabled] = useState(true);
const [focusRequest, setFocusRequest] = useState(false);
return (
<><button onClick={toggleDisabled}>
{disabled ? "Enable" : "Disable"} Textbox
</button>
<button onClick={focusInput} disabled={disabled}>
Focus Textbox
</button>
<Child disabled={disabled} shouldFocus={focusRequest} />
</>
);
}
How it works:
disabled state in Parent controls whether the child input is enabled or disabled.
function DropdownToTextbox() {
const [selectedValue, setSelectedValue] = useState("");
return (
<div>
<select value={selectedValue} onChange={handleChange}>
<option value="">Select an option</option>
<option value="Apple">Apple</option>
<option value="Banana">Banana</option>
<option value="Orange">Orange</option>
</select>
Explanation:
The select element controls the selectedValue state.
function TextareaWithCharCount() {
const maxLength = 100;
const textareaRef = useRef(null);
const [remaining, setRemaining] = useState(maxLength);
return (
<div>
<textarearef={textareaRef}
maxLength={maxLength}
onChange={handleChange}
rows={4}
cols={40}
/>
<div>{remaining} characters remaining</div>
How it works:
return (
<div>
<inputtype="text"
placeholder="Search fruits..."
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
/>
<ul>
{filteredItems.length > 0 ? (
filteredItems.map((item, idx) => <li key={idx}>{item}</li>)
):(
<li>No results found</li>
)}
</ul>
</div>
);
};
How it works:
The list items is filtered to include only those matching the searchTerm .
function RadioToTextbox() {
const [selectedOption, setSelectedOption] = useState("");
return (
<div>
<h3>Select an option:</h3>
<label>
<inputtype="radio"
value="Option 1"
checked={selectedOption === "Option 1"}
onChange={handleChange}
/>
Option 1
</label>
<br />
<label>
<inputtype="radio"
value="Option 2"
checked={selectedOption === "Option 2"}
onChange={handleChange}
/>
Option 2
</label>
<label>
Selected option:
<input type="text" value={selectedOption} readOnly />
</label>
</div>
);
}
componentDidCatch(error, info) {
if (this.props.onError) {
this.props.onError(error, info);
} else {
render() {
if (this.state.hasError) {
return this.props.fallback || <div>Something went wrong.</div>;
}
return this.props.children;
}
}
Usage example:
function App() {
return (
<ErrorBoundaryfallback={<div>Oops—an error occurred.</div>}
onError={(error, info) => {
// send to logging service
console.log('Logging error:', error, info);
}}
>
<MyComponent />
</ErrorBoundary>
);
}
You can pass a fallback prop (any JSX) and an onError callback.
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h2>Count: {count}</h2>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => setCount(count - 1)} disabled={count === 0}>
Decrement
</button>
<button onClick={() => setCount(0)}>
Reset
</button>
</div>
);
}
function Counter() {
const [state, dispatch] = useReducer(counterReducer, initialState);
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>Counter: {state.count}</h1>
<div>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>
<button
onClick={() => dispatch({ type: 'RESET' })}style={{ margin: '0 10px' }}>
Reset
</button>
2. Key Features
1. Reducer Function:
2. Action Types:
3. useReducer Hook:
4. UI Elements:
3. How to Use:
1. Create a new file Counter.js with the above code
function App() {
return (
<div className="App">
<Counter />
</div>);
}
✅ Syntax:
useEffect(() => {
// This runs after every render (initial + re-renders)
yourMethod();
});
🔧 Example:
import React, { useState, useEffect } from 'react';
function ReRenderExample() {
const [count, setCount] = useState(0);
useEffect(() => {
logMessage();
⚠️
}); // No dependency array → runs after every render
return (
<div>
<h2>Count: {count}</h2>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
📌 Explanation:
useEffect() without a dependency array runs after every render.
Each time the component state or props change, it re-renders → triggering the
useEffect .
⚠️ Caution:
Avoid expensive logic inside this useEffect since it runs frequently. Use
dependencies wisely for performance.
// child.component.ts
import { Component, Input } from '@angular/core';
// parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<h1>Parent Component</h1>
<app-child
[parentMessage]="message"
[userData]="user"
></app-child>
`})
export class ParentComponent {
message = "Hello from Parent!";// Data to send
user = { name: 'Alice', age: 30 };// Object data}
2. Parent Component: Listens for this event and triggers its own method.
3. Data Flow: Child emits events with optional data payloads → Parent catches
and responds.
@Component({
selector: 'app-child',
template: `
<div class="child">
<h2> 🌼
Child Component</h2>
<button (click)="sendMessageToParent()">
Send Message
</button>
</div>
`})
export class ChildComponent {
// 1. Declare output event emitter
@Output() messageSent = new EventEmitter<string>();
sendMessageToParent() {
const message = "Hello from child!";
@Component({
selector: 'app-parent',
template: `
<div class="parent">
<h1> 🌳
Parent Component</h1>
<p>Child's message: {{ childMessage }}</p>
// component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-dropdown',
templateUrl: './dropdown.component.html',
})
export class DropdownComponent {
// Array of objects
countries = [
{ id: 1, name: 'India' },
{ id: 2, name: 'USA' },
{ id: 3, name: 'Canada' },
];
<select [(ngModel)]="selectedFruit">
<option *ngFor="let fruit of fruits" [value]="fruit">
{{ fruit }}
</option>
</select>
<select [(ngModel)]="selectedCountryId">
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [DropdownComponent],
bootstrap: [DropdownComponent],
})
export class AppModule {}
Explanation
ngFor loops through the array.
bound variable.
Output Example:
Selecting a fruit like "Banana" would set selectedFruit to "Banana" .
lazy.module.ts
lazy-routing.module.ts
@NgModule({
declarations: [LazyComponentComponent],
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LazyRoutingModule { }
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {
Explanation:
Lazy loading means the LazyModule and its components won't load initially, only
loading when the user navigates to the /lazy route.
2. Component TypeScript:
@Component({
selector: 'app-input-display',
templateUrl: './input-display.component.html'
})
export class InputDisplayComponent {
userInput: string = '';
}
Explanation:
[(ngModel)] provides two-way binding, automatically syncing input changes with
the component’s userInput property.
The second input uses property binding ( [value] ) to reflect the current value of
userInput .
Remember:
Ensure you import FormsModule in your module:
@NgModule({
This approach automatically updates the second textbox as you type in the first
one.
Using ngIf :
HTML:
<div *ngIf="showElement">
This element is conditionally rendered.
</div>
Component:
<div>
{{ showElement ? 'Element is visible!' : 'Element is hidden!' }}
</di
<ng-template #loggedOut>
Please log in.
</ng-template
Component:
typescript
CopyEdit
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
Component Implementation:
//component.ts
@Component({
selector: 'app-debounce',
templateUrl: './debounce.component.html',
})
export class DebounceComponent implements OnInit {
ngOnInit(): void {
this.searchControl.valueChanges.pipe(
debounceTime(500), // waits for 500ms pause
distinctUntilChanged() // triggers only if value changes
)
.subscribe(value => {
this.onSearch(value);
});
}
HTML:
Explanation:
debounceTime(500) : waits 500 milliseconds after typing stops before emitting the
event.
distinctUntilChanged() : ensures the subscribed event triggers only if the value has
changed.
debounceTimer: any;
HTML
@NgModule({
imports: [
HttpClientModule
]
})
export class AppModule { }
fetchData(): Observable<any[]> {
@Component({
selector: 'app-fetch-data',
templateUrl: './fetch-data.component.html'
})
export class FetchDataComponent implements OnInit {
ngOnInit() {
this.dataService.fetchData().subscribe({
next: (response) => {
this.data = response;
this.loading = false;
},
error: (err) => {
this.error = err.message || 'Error fetching data';
this.loading = false;
}
});
}
Explanation:
Service ( HttpClient ) is the recommended way to fetch API data.
Now your Angular component cleanly fetches and displays data from an API.
b. Component TypeScript
@Component({
selector: 'app-country-state-dropdown',
templateUrl: './country-state-dropdown.component.html'
})
export class CountryStateDropdownComponent {
countries = countries;
allStates = states;
selectedCountryId: number = 0;
filteredStates: any[] = [];
onCountryChange(countryId: string) {
const id = +countryId;
c. Component HTML
@NgModule({
imports: [FormsModule]
})
// component.ts
export class MyComponent {
htmlContent: string = "<p style='color:red;'>This is dynamic HTML content</
p>";
}
In the template:
@Component({
selector: 'app-my-component',
templateUrl: './my.component.html'
})
Template:
<div [innerHTML]="htmlContent"></div>
Summary:
Use [innerHTML] binding to render HTML from string.
If the content is dynamic and from an external source, sanitize or trust it via
DomSanitizer .
Avoid direct string interpolation with {{ }} because Angular will escape HTML
as plain text.
Basic steps:
2. Angular’s change detection will automatically update the view if you mutate
the array properly or replace it.
Example
Component ( example.component.ts ):
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent {
items: string[] = ['Apple', 'Banana', 'Cherry'];
addItem() {
this.items.push('Date');
// Alternatively, to trigger change detection safely:
// this.items = [...this.items, 'Date'];
}
removeItem(index: number) {
this.items.splice(index, 1);
}
Template ( example.component.html ):
<ul>
<li *ngFor="let item of items; let i = index">
{{ item }}
<button (click)="removeItem(i)">Remove</button>
</li>
</ul>
Mutating the array (e.g., .push() , .splice() ) usually works fine because Angular's
default change detection detects these changes in most cases.
This triggers Angular to detect a new array and update the template
accordingly.
Always bind your template with ngFor or other directives that react to data
changes.
3. On input change, update textbox state or focus inside the child component.
// child.component.ts
import { Component, Input, OnChanges, SimpleChanges, ViewChild, ElementR
ef } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<input #inputBox type="text" [disabled]="isDisabled" />
`
})
export class ChildComponent implements OnChanges {
@Input() isDisabled: boolean = false;
@Input() shouldFocus: boolean = false;
ngOnChanges(changes: SimpleChanges) {
if (changes['shouldFocus'] && this.shouldFocus) {
// Focus input when shouldFocus becomes true
setTimeout(() => this.inputBox.nativeElement.focus(), 0);
}
}
}
@Component({
selector: 'app-parent',
template: `
<button (click)="toggleTextbox()">Toggle Enable/Disable</button>
<button (click)="focusTextbox()">Focus Textbox</button>
<app-child
[isDisabled]="isTextboxDisabled"
[shouldFocus]="shouldFocusTextbox">
</app-child>
`
})
export class ParentComponent {
isTextboxDisabled = false;
shouldFocusTextbox = false;
toggleTextbox() {
this.isTextboxDisabled = !this.isTextboxDisabled;
}
focusTextbox() {
this.shouldFocusTextbox = true;
// Reset after focus to allow future focus toggles
setTimeout(() => this.shouldFocusTextbox = false, 100);
}
}
Explanation:
The parent toggles isTextboxDisabled to enable/disable the textbox in the child.
The child detects changes in inputs using ngOnChanges and focuses the input
programmatically.
2. Bind the textbox’s value to the same property (or a derived one).
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
selectedValue: string = '';
options = ['Apple', 'Banana', 'Cherry'];
}
app.component.html
<br />
Explanation:
[(ngModel)]="selectedValue" binds the dropdown selected value two-way.
Example
component.ts
@Component({
selector: 'app-char-count',
templateUrl: './char-count.component.html',
})
export class CharCountComponent {
maxChars = 100;
currentLength = 0;
onInput(event: Event) {
const input = event.target as HTMLTextAreaElement;
this.currentLength = input.value.length;
}
}
component.html
<textarea
#myTextarea
(input)="onInput($event)"
[attr.maxLength]="maxChars"
></textarea>
Example
component.ts
@Component({
selector: 'app-char-count',
templateUrl: './char-count.component.html',
})
export class CharCountComponent implements AfterViewInit {
@ViewChild('myTextarea') myTextarea!: ElementRef<HTMLTextAreaElement
>;
maxChars = 100;
currentLength = 0;
ngAfterViewInit() {
this.myTextarea.nativeElement.addEventListener('input', () => {
this.currentLength = this.myTextarea.nativeElement.value.length;
});
}
}
Summary:
Template Reference Bind (input) event and update Simple and declarative,
Variable length directly preferred way
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
<inputtype="text"
placeholder="Search items"
[(ngModel)]="searchText"
/>
<ul>
<li *ngFor="let item of filteredItems">{{ item }}</li>
typescript
Copy
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // import FormsModule here
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule],
bootstrap: [AppComponent],
})
export class AppModule {}
How it works:
The user types in the textbox ( searchText bound via ngModel).
The getter filteredItems filters the original list based on the search string.
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
selectedOption: string = '';
onSelectionChange(value: string) {
this.selectedOption = value;
}
}
How it works:
When a radio button is selected, the onSelectionChange method is called with the
value of the selected option.
// error-boundary-handler.service.ts
import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { ErrorBoundaryService } from './error-boundary.service';
@Injectable()
export class ErrorBoundaryHandler implements ErrorHandler {
constructor(private injector: Injector) {}
handleError(error: any) {
const errorBoundaryService = this.injector.get(ErrorBoundaryService);
errorBoundaryService.setError(error);
// error-boundary.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
setError(error: any) {
this.errorSubject.next(error);
}
clearError() {
this.errorSubject.next(null);
}
}
// error-boundary.component.ts
import { Component } from '@angular/core';
import { ErrorBoundaryService } from './error-boundary.service';
@Component({
selector: 'app-error-boundary',
template: `
<ng-container *ngIf="error$ | async as error; else content">
<div class="error-fallback">
<h2>Something went wrong!</h2>
<pre>{{ error?.message || error }}</pre>
<button (click)="clearError()">Try Again</button>
</div>
</ng-container>
<ng-template #content>
<ng-content></ng-content>
</ng-template>
clearError() {
this.errorBoundaryService.clearError();
}
}
@NgModule({
declarations: [AppComponent, ErrorBoundaryComponent],
imports: [BrowserModule],
providers: [
If an error occurs anywhere in the child components, the error boundary will show
fallback UI.
Summary:
ErrorBoundaryHandler catches uncaught errors globally.
src/app/counter/
├── counter.component.ts
├── counter.component.html
├── counter.component.css
└── counter.component.spec.ts
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.css']
})
export class CounterComponent {
count = 0;
increment(): void {
this.count++;
}
decrement(): void {
this.count--;
}
✅ Explanation:
count is a class property that stores the current counter value.
<div class="counter">
<h2>Counter Value: {{ count }}</h2>
<div class="buttons">
<button (click)="decrement()">–</button>
<button (click)="reset()">Reset</button>
<button (click)="increment()">+</button>
</div>
</div>
✅ Explanation:
{{ count }} : Angular interpolation to display the counter value.
✅
210 Interview questions & Answers - Saikrishna Nangunuri 245
✅ Step 4: Add Styles (Optional)
🔹 counter.component.css
.counter {
text-align: center;
margin-top: 2rem;
font-family: Arial, sans-serif;
}
.buttons {
display: flex;
justify-content: center;
gap: 1rem;
margin-top: 1rem;
}
button {
font-size: 1.5rem;
padding: 0.5rem 1rem;
cursor: pointer;
}
<app-counter></app-counter>
Make sure it's declared in app.module.ts (done automatically when generated with
CLI).
✅ Output
210 Interview questions & Answers - Saikrishna Nangunuri 246
A fully working Angular counter that looks like this:
less
CopyEdit
Counter Value: 0
[ - ] [ Reset ] [ + ]
✅ What is ngDoCheck() ?
ngDoCheck()is a lifecycle hook that Angular calls during every change detection
run, i.e., whenever the component is checked for changes, which happens:
on events,
@Component({
selector: 'app-my-component',
constructor() {}
ngDoCheck(): void {
this.onEveryRerender(); // Called during every change detection run
}
onEveryRerender(): void {
console.log('Component re-rendered!');
}
triggerChange(): void {
// This method is to trigger a change
this.counter++;
}
}
🔹 HTML Template
<h2>Counter: {{ counter }}</h2>
<button (click)="triggerChange()">Increase Counter</button>
✅ Explanation:
ngDoCheck() is triggered on every Angular change detection.
Inside it, we call onEveryRerender() which logs a message or performs any logic.
Clicking the button updates the counter, which causes a change detection →
which calls ngDoCheck() .
⚠️
210 Interview questions & Answers - Saikrishna Nangunuri 248
⚠️ Note:
Use ngDoCheck() carefully because it's called very frequently.