Design a site like this with WordPress.com

## Euler’s Number e : A Dart (Flutter) Implementation

Introduction: Euler’s Number , also known as Euler’s Constant and denoted by ‘e’ is a constant value as well as an irrational number . Its approximate value is 2.718281828459045, or 2.71828 in short for quick calculation . Most modern programming languages include this value in their Math libraries, for example: C++’s exp() or Dart’s e displays the Euler’s Constant .

We shall write a Dart (Flutter) program to calculate the Euler’s Number, ‘e’ :

import ‘dart:math’;

// class to work with Euler’s value
class CalculateEuler{

// method to calculate ‘e’
void calculateEuler(){

// taking a specific constant named special_constant to calculate ‘e’
int special_constant = 99999991726;

// calculating ‘e’ without Math library’s assistance
num calculated_euler = pow((1 + (1/special_constant)),special_constant);

// displaying the calculated (approximate) ‘e’
print(“My Calculation: ” + calculated_euler.toString());
}
}

void main() {

// taking an instance of CalculateEuler class
CalculateEuler euler = CalculateEuler();

// calling the method on the instance
euler.calculateEuler();

// displaying the original value of ‘e’ from Dart’s Math library
print(“Actual e: ” + e.toString());
// print(exp(1)) displays the same value of ‘e’
}

The calculated value in this Dart (Flutter) program results in 2.7182818284464436 that is close to the actual value of ‘e’ (i.e. 2.718281828459045) that is showed as well .

Applications of Euler’s Number:

‘e’ is found to be used far and wide, including but not limited to:
1. Probability
2. Radioactivity
3. Pharmaceuticals
4. Bernoulli Trials
5. Standard Normal Distribution

Advertisement

## Flutter’s Concurrency: Isolate & Async-Await in Dart

Isolate: An isolate is a specific chunk of memory generated by Dart to handle specific tasks . One isolate can be tasked to handle a single or multiple tasks asynchronously . If there is a need to perform high-computation or intensive task, that is where isolates enable Dart to achieve concurrency and multithreading . An isolate’s concept may sound similar to multithreads in other languages .

Isolate Advantages:
1. Achieving Concurrency
2. Each isolate’s state is secured from other isolates’ interference
3. No Mutex or Thread Lock due to separate memory heap for each isolate
4. Performing multiple independent tasks at a time
5. Offloading heavy computation to worker isolates (as background workers)

Async-Await: ‘async’ and ‘await’ are two keywords reserved in Dart language and used with Flutter . When the main isolate does multiple works at a time to get things done faster, this characteristic is called to be asynchronous . ‘await’ keyword is used before the function that runs to bring the result .

The Dart program below implements isolates to calculate separately and finally displays each Isolate’s ID:

import ‘dart:isolate’;
import ‘dart:developer’;

// iso() takes a number and performs addition using specific different Isolates void iso(var n){
print(‘\${n+n} and isolate ID is: ‘);
// displaying Isolate ID to ensure the difference
print(Service.getIsolateID(Isolate.current));
}

void main() async {
// Spawning (Producing) three different Isolates
await Isolate.spawn(iso,9);
await Isolate.spawn(iso,200001);
await Isolate.spawn(iso,1);
// The kill() function kills an Isolate
// Isolate.kill(priority: Isolate.immediate);
}

Communication Between Or Among Isolates By Message Passing

One isolate can not interrupt another isolate’s state, data or memory. When they need to communicate with each other, an isolate passes asynchronous messages through a SendPort and the intended receiver isolate receives those messages through its correspnding ReceivePort .

The Dart program below highlights message passing between isolates:

import ‘dart:io’;
import ‘dart:async’;
import ‘dart:isolate’;

Isolate? isolate;

start() async {
// The port for an isolate to receive messages
ReceivePort receivePort= ReceivePort();
isolate = await Isolate.spawn(runTimer, receivePort.sendPort);
receivePort.listen((data) {
stdout.write(‘Receiving: ‘ + data + ‘, ‘);
});
}

void runTimer(SendPort sendPort) {
int counter = 0;
Timer.periodic(new Duration(seconds: 1), (Timer t) {
counter++;

String msg = ‘notification ‘ + counter.toString();
stdout.write(‘Sending: ‘ + msg + ‘ -> ‘);
sendPort.send(msg);
});
}

stop() {
if(isolate != null) {
stdout.writeln(‘Stopping the isolate.’);
//  isolate.kill(priority: Isolate.immediate);
isolate = null;
}
}

void main() async {
stdout.writeln(‘Starting an isolate.’);
await start();
stdout.writeln(‘Press the Enter key to stop.’);
await stdin.first;
stop();
stdout.writeln(‘Ending the program.’);
exit(0);
}

## Optimize Flutter Apps: Fast Flutter App Performance

Flutter is performant by default . Developers behind Flutter and Dart have spent an enormous amount of time to make their performance near-native . However, as we have recently developed & released the Rokomari app , Bangladesh’s largest online bookseller app using Flutter (Dart) – I have found several peak-points that require optimization .

Flutter, powered by Dart language, is an open-source SDK by Google to develop apps for Android, iOS, Linux, Windows, MacOS and the web from a single codebase .

Here, I share tips to optimize a Flutter app, from my experience, that scales:

1. Avoid heavy-works on the main thread
2. Employ isolates wherever necessary
3. Mark static widgets as const
4. Avoid rebuilding widgets
5. Remove Container() if unnecessary
6. Prefer SizedBox() or Nil() instead of blank Container()
7. Use StatelessWidget if StatefulWidget is of no use
8. Keep the Widget build() as simple as possible
9. Avoid color gradients
10. Add shrinkWrap:true to ListView.builder
11. Apply RepaintBoundary() in animation works
12. Cache both local and networked images
13. Employ dispose() to release object memories
14. Compress (encode and decode) data
15. Make Color codes const
16. Keep Flutter and Dart up-to-date
17. Produce architecture-specific builds separately for phones, tablets and desktops

These tips will ensure a fast & lightweight high-performing Flutter app that runs on multiple platforms .

## Provider: State Management in Flutter

What is State Management?
The state of an app is any data that exists in the memory when the app is running . This state is crucial to rebuild the UI . It may range from assets to variables whose change of value may affect the UI .

What does Provider do?
Provider is Google’s recommended way of handling an app’s state . It can be imported and used in the form of a package available at www.pub.dev .

Advantages of Provider
(1) Change of state across the app
(2) Low complexity
(3) Developer-friendly

Steps to Provider
(1) Install the package
(2) Import the package
(3) Declare the class name and the widget name inside ChangeNotifierProvider
(4) Put business logic or the values to be updated inside Change Notifier followed by notifyListeners() to listen for change
(5) Call the function to activate and view the state change inside a widget or class

Provider Implementation in Flutter (Dart)

import ‘package:flutter/material.dart’;
import ‘package:provider/provider.dart’;

void main() {
// Declare the class name and the widget name inside ChangeNotifierProvider
runApp( ChangeNotifierProvider(
create: (_) => CountNotifier(),
child: CounterApp(),),
);}

// logic or the values to be updated stay here
class CountNotifier with ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void incrementCounter() {

// testing the value change in Log / Run using debugPrint()
debugPrint(“Incrementing and notifying”);
_counter++;

// using listeners to notify the change
notifyListeners();
}}
class CounterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,),
home: MyHomePage(title: ‘CounterApp (Provider + ChangeNotifier)’),
);}}

class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key? key, required this.title}) : super(key: key);
@override)
Widget build(BuildContext context) {
debugPrint(“Tishan builds Flutter Provider”);
return Scaffold(
appBar: AppBar( title: Text(this.title),),
body: Center( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(‘Your number of clicks so far today is: ‘),
// updating and displaying the changed-value in a Text widget
Text(‘\${context.watch<CountNotifier>().counter}’,
),],),),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<CountNotifier>().
incrementCounter(),
tooltip: ‘Increment’,
child: Icon(Icons.add),),
);}}

// One may display the state-change elsewhere in another widget similarly

## Palindrome Number in Swift

A Palindrome number is a special type of number that reads the same if read in reverse . Problems relating to Palindrome are common in both programming and mathematics . We shall implement a program to implement Palindrome number in Swift language .

A short note on Swift: Swift is an open-source programming language developed by Apple Inc. to make apps for iOS, MacOS, tvOS & watchOS .

Steps:
1. Taking a variable to store a number (to test if that number is Palindrome) and another variable assuming as the reverse number (initially as Flag Variable, 0)
2. Reversing the original (or, taken as user-input)
3. If the reversed number equals to the original number, it is a Palindrome – otherwise not .

Program to implement Palindrome number in Swift language:

var reverse = 0
// original is the variable to be tested whether it is Palindrome or not
// you may change it
var original = 1111
var num = original
func rever() {
while(num>0){
reverse = reverse * 10 + original % 10
num = num / 10
}
// comparing the reversed number to the original one
if(original==reverse){
print(“\(original) is a Palindrome number.”)
}
else{
print(“\(original) is not a Palindrome number.”)
}
}
// calling the function finally
rever()

To get the source code, visit Farial Mahmod Tishan’s github at:
https://github.com/Farial-mahmod/Palindrome-number-in-Swift

## Dart and Flutter for Multi-Platform Apps

Dart programming language has a rich set of features ( i.e. Hot Reload, Null Safety, AOT+JIT ) powering Google’s Flutter SDK to build Android, iOS, Web, Linux, Windows & Embedded System apps from a single codebase.

You may try here:
Learn Flutter: https://flutter.dev/
Learn Dart: https://dart.dev/
Practise Dart: https://dartpad.dev/

#flutter #dart #android #ios #windows #linux #embedded #desktop

## WebView Mobile App

A WebView mobile app shows a web application in the form of a mobile application in a flexible yet fantastic way. In simple terms, a WebView app resembles a website’s view when opened from a mobile browser.

Advantages of a webview app:
1. Replicates a website’s view inside a mobile app
2. Time-saving in terms of time-constrained development

Disadvantages of a webview app:
1. Show the features only available on the web application
2. Tough to add new feature on the mobile-side

Program (Java):

package com.khalnayak.webview;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

WebView web;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

web = findViewById(R.id.webview);
WebSettings webSettings = web.getSettings();

// JavaScript must be enabled to view the site
webSettings.setJavaScriptEnabled(true);
web.setWebViewClient(new Callback());

// web URL to show the view
web.loadUrl("https://softwarewall.code.blog/");
}

private class Callback extends WebViewClient{
@Override
public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event){
return false;
}
}
}

GitHub Source Code link: https://github.com/Farial-mahmod/Webview-mobile-app

## Picasso Library in Android

Picasso is a widely used library in Android Studio. It helps to load images of various formats. Images can be edited, resized and cropped using Picasso. It is named after the famous Spanish painter Pablo Picasso.

Steps to use Picasso:

1. In build.gradle, add implementation ‘com.squareup.picasso:picasso:2.5.2’

2. In Manifest file, add <users-permission android:name=”android.permission. INTERNET”/>

3. In layout file, add an <ImageView />

4. In Activity Java file, import the library by adding “import com.squareup.picasso.Picasso;” statement

5. Loading the image inside the Activity Java file:
ImageView imageView = findViewById(R.id.imageView);
Picasso.with(this)
.load(“url/img”)
.into(imageView);

6. To resize, simply add this to the Picasso instance:
.resize(size, size);

7. To add a placeholder, simply add this to the Picasso instance:
.placeholder(R.mipmap.ic_launcher);

8. To crop and make it fit, add this to the Picasso instance:
.centerCrop()
.fit();

Any further information can be found at https://github.com/square/picasso .

## Hyperledger Fabric : demystified

Introduction

Hyperledger is a project that consists of several frameworks and tools to implement private and permissioned blockchain. Initiated by the Linux Foundation that has a rich heritage of open source contribution, the Hyperledger project has been contributed by several giants, including IBM, Intel, Hitachi, Daimler, Samsung and Walmart – to name a few.

Fabric is a framework of the Hyperledger project that has been widely adopted by the industry to meet the demand of private blockchain. IBM boasts the lion’s share of contribution to this framework’s development so far. This framework has several advantages that make it ideal when it comes to permissioned blockchains. Fabric Samples is the greatest and smoothest work to get up and running.

Characteristics

1. Private Channels: Unlike Bitcoin and Ethereum, member to member private communications and transactions are supported.
2. Permissioned Network: Each entry to the network is permissioned and controlled.
3. Security: Certificate Authority and Membership Service Provider ensures overall security of the blockchain’s each transaction.
4. Distributed Ledger: Each peer and channel has its own copy of the ledger.
5. Chaincode Variety: One may write chincode in Golang, JavaScript, Java or TypeScript – all are allowed and valid.
6. Ledger Options: Options to store data either using LevelDB or CouchDB.

Installation

1. Download and install Golang ( https://golang.org/dl/ )
2. Install Git
3. Get cURL
4. Clone the hyperledger/fabric-samples from github
5. Download platform-specific binaries (/bin) and config files (into /config)
6. Download the Hyperledger Fabric docker images
7. Get platform-specific binaries (inside /bin) by: curl -sSL https://bit.ly/2ysbOFE | bash -s
8. Setting PATH environment variable by: export PATH=<path to download location>/bin:\$PATH

Whirlwind Tour of Directories

Fabric-Samples get one started with testing and customizing his / her own transaction logics . It consists of several sub-directories such as:

(a) asset-transfer sub-directories contain sample transaction logics (Go, Java, JavaScript and TypeScript) to develop business logic, make private channels and work with ledgers right out-of-the-box

(b) chaincode folder holds chaincodes (similar to smart contracts) to get started

(c) test-network brings up a sample network of two organizations, each consisting of two peer nodes to implement a practical blockchain

(d) token-utxo is there if someone needs to produce ICOs or Coins in a project

(e) README.md highlights an overview of sample ready-to-use projects

Hyperledger Fabric framework is still under development. As it is open-source, anyone may contribute to enrich this framework at https://hyperledger-fabric.readthedocs.io/en/release/CONTRIBUTING.html .

## Inspecting Ethereum’s Blocks: The Web3py Way

Ethereum is a public blockchain used worldwide. It has rich features to implement “Smart Contracts”. A smart contract is basically a program that contains the business-logic and transaction related conditions that has to be deployed on a specific peer.

Web3py: It is a Python library that eases the interaction between the client and the Ethereum blockchain.
Infura: This is a node provider that lets us use remote nodes without prior setup.

The following program connects to the Ethereum blockchain and inspects block-specific details:

##### Importing Web3 library:

from web3 import Web3

##### Place your infura API key:

Infura_Connection = “https://mainnet.infura.io/v3/INFURA_KEY&#8221;

##### Producing the connection to the blockchain:

web3 = Web3(Web3.HTTPProvider(Infura_Connection))

##### Checking protocol version:

print(web3.eth.protocolVersion)

##### Fetching the latest block:

print(web3.eth.getBlock(‘latest’))

##### Displaying coinbase:

print(web3.eth.coinbase)

##### Prints the current hashrate that is to be mined to add a block:

print(web3.eth.hashrate)

##### Checking if nodes are sycing properly or dead:

print(web3.eth.syncing)

##### fetching ChainID:

print(web3.eth.chainId)

##### Displaying block number:

print(web3.eth.blockNumber)

##### Input account key to get balance in Wei unit:

myBalance = web3.eth.getBalance(“YOUR_ACCOUNT”)
print(myBalance)

##### Current gas price in Wei unit:

print(web3.eth.gasPrice)

For any queries, official documentation can be consulted.

## Redis Overview

Redis is a project by Redis Labs whose sole purpose is to implement an in-memory database that supports various data structures. Originally developed by Salvatore Sanfilippo in 2009, its current version is 6.0.9 as of September 11, 2020.

Redis is open-source and is under BSD license. Mainly its of key-value nature and written in ANSI C.

### Useful Redis Commands

1. Setting a value:
SET chapter 67
2. Retrieving a value:
GET chapter
“67”
3. Setting multiple key-values:
MSET start “Fatiha” complete “Naas”
OK
4. Incrementing a value:
INCR chapter
(integer) 68
5. Decrementing a value:
DECR chapter
(integer) 67
6. If a value exists:
EXISTS chapter
(integer) 1
7. When a value exists not:
EXISTS name
(integer) 0
8. Removing a value:
DEL chapter
(integer) 1
9. Removing all keys:
FLUSHALL
OK
10. Setting a server name:
SET server:name Zend
OK
11. Getting a server name:
GET server:name
“Zend”
12. Setting a server port:
SET server:port 8083
OK
13. Getting a server port:
GET server:port
“8083”
14. Renaming a key:
RENAME chapter sura
OK
15. Authenticating a user:
AUTH MyUserName PasswordIs123
OK
16. Assigning a name to current connection:
CLIENT SETNAME Farial
17. Retrieving the current client’s name:
CLIENT GETNAME
“Farial”
18. Printing any value:
ECHO “Quran.”
“Quran.”
19. Closing server connection:
QUIT
OK
20. Setting a hash value:
HSET myhash f1 5
1
21. Getting the hash value:
HGET myhash f1
“5”
22. Getting number of hash fields:
HLEN myhash
1
23. Adding key-value to a list:
LPUSH ThisList 1 2 3
(integer) 3
24. Sorting a list:
SORT ThisList
1 2 3
(Sorts in ascending order, to reverse the sorting – add DESC to the command)
25. Removing the last value from list:
LPOP ThisList
“3”
26. Adding members to aset:
SADD Set 3 2 1
(integer) 3
27. Checking members of a set:
SMEMBERS Set
(1)”3″
(2)”2″
(1)”1″
28. Joining two sets:
SUNION Set1 Set2
29. Difference between two sets:
SDIFF Set1 Set2

There are more commands available to work with a Redis database if you need. You may find them on http://www.redis.io .

## Getting Started With GIT

GIT is a version control system that tracks all the changes in a project or file. It is widely used by developers all over the world due to its simplicity and efficiency. GIT and GitHub are not the same – GitHub is an online host or storage where files or projects can be saved, updated or edited using GIT.

” So, GIT is like your Keyboard
whereas
GitHub is your Computer Memory. “

GIT is:

1. Open Source
2. Free
3. Distributed
4. Fast
5. Efficient

GIT Commands

1. git init initiates a new local repository
2. git status shows current project status
3. git add . copies all the files to the repository
4. git add FileName adds a specific file to the repository
5. git commit -m “Your Message” commits and highlights a message
6. git remote add origin <URL> connects the local repository to the URL-linked online repository
7. git push origin master pushes changes to the remote repository
8. git log highlights all the commits
9. git blame FileName shows the users that updated the file with time
10. git branch -av displays all the connected branches
11. git branch BranchName produces a new branch
12. git branch -d BranchName deletes a branch
13. git remote show RemoteRepo gives information on a remote repository
14. git fetch RemoteRepo downloads information from a remote repository
15. git merge adds a branch to the current Head
16. git pull RemoteRepo BranchName works as fetch+merge action
17. git mergetool initiates the mergetool to resolve conflicts

These commands would be extremely helpful to get started with GIT version control system.

## Knowing JIT

Just-In-Time Compiler is a special type of compiler, or component of an environment that combines the power of compilation and interpretation to boost performance. It is a mid-way between compiling and interpreting. Although the term was coined by James Gosling later, John McCarthy and Ken Thompson are the pioneers in developing this technology.

Functionality

A JIT compiler’s execution is done at two stage: compile time & run time.

1. Compile Time: A program is turned into an intermediate form (bytecode). At this level, the the intermediate code is quite slow.
2. Run Time: Here, the bytecode is powered by JIT to be compiled targeting CPU-specific architecture. The bytecode is turned into machine code (known as dynamic compilation). As a result, performance dramatically upgrades.

Advantages

• Speed-boost
• Interpreter-like flexibility
• Cache optimization
• Better performance than interpreter and static compiler

Applications

• JVM (Java)
• Common Language Runtime(C#)
• Dalvik Virtual Machine
• Android Runtime
• PHP (from version 8.x)

## Composer: PHP’s Package Manager

Composer is a package manager for the PHP programming language, its frameworks (i.e. Laravel, Symphony, CodeIgniter and more), Ecommerce platforms (i.e. Magento) and Content Management Systems (i. e. Drupal, SilverStripe) . Developed by Nils Adermann and Jordi BoggianoIt (2012), it deals with software distributions as well as performing package-related operations from installing to updating to removing. As a dependency manager, Composer handles necessary libraries and dependencies.

Installation Process

There are several ways to download and install Composer.

• Through script: Running this script initiates the installer, runs and after successfully installing, removes the installer:
php -r “copy(‘https://getcomposer.org/installer&#8217;, ‘composer-setup.php’);”
php -r “if (hash_file(‘sha384’, ‘composer-setup.php’) === ‘e0012edf3e80b6978849f5eff0d4b4e
4c79ff1609dd1e613307e16318854d
24ae64f26d17af3ef0bf7cfb710ca747
55a’) {
echo ‘Installer verified’;
}
else {
echo ‘Installer corrupt’;
unlink(‘composer-setup.php’);
} = echo PHP_EOL;”
php composer-setup.php php -r “unlink(‘composer-setup.php’);”

This script has been developed for version 1.10.1 (As of 2020-03-13). Kindly, have a look at https://getcomposer.org/download to see changes for newer versions.
• Directory-specific Installation: To install to a specific directory, open your command-line terminal and run:
php composer-setup.php –install-dir=bin
To download a specific version, for example, ” 1.0.0-alpha8”, add the –version flag like below:
php composer-setup.php –version=1.0.0-alpha8
• Manual Downlaod: To manually download, visit https://getcomposer.org/download/ and click on your preferred version.

Commands

Composer commands can be run flexibly from the cmd (command line interface). Widely used Composer commands are mentioned below:

1. Adding Packages: To add any package to your project, open your command-line and type:
composer require vendor/package
Example: composer require laravel/socialite
(adding –dev inserts the package into composer.json’s require-dev section and then install)
2. Installing Libraries & Dependencies: To install libraries and dependencies mentioned in the composer.json file: composer install
3. Updating Packages: There are various types of updating options available.
(a) To update all the packages: composer update
(b) To update all the packages along with their dependencies:
composer update –with-dependencies
(c) To update a certain package: composer update vendor/package
(d) To update a specific vendor’s all packages: composer update vendor/*
(e) To update composer.lock without updating any package:
composer update –lock
(f) To update the autoloader: composer dumpautoload
(adding -o ensures optimization)
4. Removing Packages: To remove a specific vendor & its package name from the composer.json and uninstall that package:
composer remove vendor/package

Composer is the de facto dependency cum package manager for PHP and its allies. Moreover, packages from Packagist can be easily installed using Composer.

## Single Page Application

A Single Page Application (SPA) refers to a modern web application that can load its sections dynamically as required, rather than traditional full-page loading. It requires the combined use of several frontend technologies to build an SPA. Development of such applications are on the rise due to the performance and advantages over traditional websites.

Features

• Native-like View
• Dynamic Rendering
• Interactive
• Flexible caching

Development

Developing a Single Page Application is more of a frontend-battle than a backend development. To speak frankly, JavaScript has taken the lead in producing Single Page Applications by all means. These are the frameworks and technologies that are intensively used to develop SPAs:

1. Frameworks: AngularJS, ExpressJS, MeteorJS, React, VueJS
2. Technologies: Ajax ,CSS, Java Applets, SSE, WebSocket, WebRTC
3. Data Handling: HTML, JSON, XML

Architecture

The working of an SPA differs from a traditional web application. At first, the client browser sends an initial request to the server and thus receives a resource or HTML in response. Next, each time the client needs to send any request to the server, it implements AJAX and the server responds to the client browser with real-time JSON data. This is how only the requested section gets dynamically updated in SPAs.

Pros

• Faster loading
• Dynamic updating
• Less use of resources
• Instant response to actions
• Suitable for real-time communication
• Offline activity
• Throughput

Cons

• Not quite SEO-friendly
• Initial load might take longer
• Incompatible with Google Analytics (as that requires full-page loading)
• Vulnerable to attacks

Real-world Examples

A well number of technology giants have successfully implemented the SPA technology. Some of the famous SPA sites that we use on a daily basis are:

• Gmail
• Google Drive
• Trello
• Twitter
• WhatsApp Web

Conclusion

Once SPAs achieve the ability to be crawled and indexed properly by search engines, they deserve to have a bedrock position in the web development race.