tag:blogger.com,1999:blog-54379320710294586182024-03-08T03:31:24.133-08:00On Software EngineeringSal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comBlogger212125tag:blogger.com,1999:blog-5437932071029458618.post-18523792056075844632022-03-08T15:37:00.006-08:002022-03-08T15:39:57.940-08:00Tips for Agile Database Development<p><span style="font-family: Calibri;">Relational databases still power most of our enterprise-level systems and this is not about to change. The implication for the development community is that there continues to be an impendence mismatch between the relational model of the database and the object-oriented semantics of the application domain model. This divide is so profound that our popular system development patterns strictly separate the business layer from the data layer. This dichotomy translates into a significant amount of work for a development team such as creating database schemas, tuning database performance, mapping the domain classes to data access classes and maintaining all of the above throughout the system lifetime. Just like we apply agile practices to the business layer, we must apply similar principles to the data layer, of course with a few twists. Here are some tips on how to maintain the database layer in an agile ecosystem:</span></p><div class="MsoNormal" style="margin: 0in 0in 10pt;"></div><div class="MsoNormal" style="margin: 0in 0in 10pt;"><ul><li><span style="font-family: Calibri;"><strong>Version your database.</strong> This may simply mean maintaining an integer value in a table in your database schema to indicate the version of the schema. Over time the database schema will evolve and there will inevitably be a mismatch between the application domain code and the schema it is running against. By checking the supported database version, the application domain code can spot these issues up front.</span></li></ul></div><ul><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Check version before accessing database.</strong> Make the database access code smart to check the version of the database before performing any operations. If an older version of the application needs to work with a newer schema of the database, write a compatibility layer that makes the database appear like the old schema to the older version of the application. Placing all data access code in one place helps in this scenario.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Create database upgrade and migration scripts.</strong> Create and maintain incremental database scripts that migrate a database schema from any released earlier version to any other later schema version up to the very latest version. In order to write good Unit Tests, we need to be able create any released version of the database. These scripts generally accomplish two tasks: Update the database schema and Migrate the data.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Put database access code in one place.</strong> Put all database access code in one place and have the application domain code talk to this database access code. That is, do not disperse your SQL Statements all over the place. Furthermore, create a well-defined interface for the database access code. This will facilitate creation of a Mock database access code layer that will be instrumental in creating Unit Tests for the application domain code.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Use source control.</strong> Implement source control over the Database Update scripts just like you would over any other kind of source code. This is essential to traceability of the database changes made.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Unit test database access code.</strong> Write robust Unit Tests for the database access code. These tests are separate from the Unit Tests for the application domain code. The purpose of these tests is to verify the CRUD (Create, Read, Update and Delete) behavior of your database access code.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Performance test database access code.</strong> Write performance tests to write large amounts of data using the database access code to spot inefficiencies.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Create database utilities and scripts.</strong> Create tools and scripts to allow testers and developers to create any released version of the database. A particularly useful script is a script that allows us to copy/move a database in its entirety from one machine to another. If a client reports a problem, an identical environment can then be easily created for diagnosis. These tools and scripts not only create appropriate database schema and but also populate appropriate seed data in the tables.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Integrate very often.</strong> Make database related activities part of the continuous integration cycle, just like your application domain code.</span></div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Automate as much as you can.</strong> This includes writing automated tests, continuous integration server and writing simple tools and scripts to recreate a database schema with appropriate configuration/seed data. What cannot be used easily, does not usually get used.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Write a utility for database health check.</strong> Write a utility library to verify the structure of a given database. Even though we versioned our database, it is possible some table is missing a column, a constraint is non-existent or a trigger is not present. A utility to verify the validity of a database at database object level (table, views, stored procedures..) is invaluable to diagnosing problems in testing and at client sites.</span> </div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><strong>Version compatibility matrix.</strong> Keep a compatibility matrix of what version of application works with what version of the database. Make it freely and widely available to development and onsite teams for early diagnosis of any database related issues.</span></div></li><li><div class="MsoNormal" style="margin: 0in 0in 10pt;"><span style="font-family: Calibri;"><b>Use an ORM framework.</b> When accessing database from your application, seriously consider employing an ORM framework. If you use a widely used, reputable ORM library, not only will you end up writing less code, you will also introduce fewer bugs. Building SQL queries by concatenating strings in code is error prone and opens up your application to numerous security vulnerabilities, such as SQL Injection attacks. By employing a reputable ORM, you can greatly reduce the security risk profile of your application.</span></div></li></ul>Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-45888841058107806092021-02-22T08:18:00.004-08:002021-02-22T09:15:10.269-08:00Common Linux / Unix Commands<h2 style="text-align: left;">List Files </h2><p>ls</p><p>ls -la</p><p>ls -laSh</p><p>ls -laShr</p><p>ls -laS</p><p>ls -laShR</p><p>ls -lu</p><p><br /></p><p>l - long listing</p><p>a - list all files including hidden, . and ..</p><p>A - don't show . and ..</p><p>S - sort by size</p><p>h - size in human readable format</p><p>r - sort in reverse order</p><p>R - list subdirectories recursively</p><p>u - sort alphabetically</p><h2 style="text-align: left;">Help on ls (or another command)</h2><p>man ls</p><h2 style="text-align: left;">Create Directory</h2><p>mkdir</p><h2 style="text-align: left;">Change to Path</h2><p>cd path</p><h2 style="text-align: left;">Go up directory</h2><p>cd ..</p><h2 style="text-align: left;">Update access date or create a file</h2><p>touch fname </p><h2 style="text-align: left;">Move a file</h2><p>mv fname targetdir/fname</p><h2 style="text-align: left;">Copy a file</h2><p>cp fname targetdir/fname</p><h2 style="text-align: left;">Delete a file</h2><p>rm targetdir/fname</p><h2 style="text-align: left;">Delete a directory</h2><p>rmdir targetdir</p><h2 style="text-align: left;">Edit file</h2><p>nano fname</p><h2 style="text-align: left;">Download and save url content to disk</h2><p>wget url</p><p>Reference: https://www.informit.com/articles/article.aspx?p=2858803&seqNum=2</p>Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-42477502871577551572020-04-06T12:07:00.002-07:002020-04-06T12:37:17.769-07:00Software Development Best Practices<h2>
SOLID PRINCIPLES</h2>
<h3>
S - Single Responsibility Principle</h3>
An element of code (such as module, class or function) should do one primary thing and nothing else. That is, do not build <i>Swiss army knife</i> code elements. For example, a function that changes the <i>case</i> of a string should <u>not</u> <i>trim</i> it as well.<br />
<h3>
O - Open/Closed Principle</h3>
Do not alter the foundational code (such as base classes and common functions) but rather compose or extend them. Modules, classes and functions should be open for extension but closed for modification. The initial functionality should not be changed but may be extended via composition or inheritance.<br />
<h3>
L - Liskov Substitution Principle</h3>
Program to interfaces. Your business logic should be programmed against class interfaces (<i>not</i> concrete implementation of classes). A subclass should have "is a" relationship with the base class. Wherever you can use a base class, you <i>should</i> be able to use a derived class.<br />
<h3>
I - Interface Segregation Principle</h3>
Interfaces should be minimal and tailored to the function they need to perform. Minimize the number of methods in a given interface. Instead, expose multiple smaller interfaces. Clients can choose to implement just the interfaces they require.<br />
<h3>
D - Dependency Inversion Principle</h3>
Do not use concrete implementations directly. High level modules should <i>not</i> depend on lower level modules. Constructors for higher level modules should accept abstractions (interfaces) of lower level modules. At <i>runtime</i>, Dependency Container injects a concrete instance of the abstraction into the constructor.<br />
<h2>
SEPARATION OF CONCERNS</h2>
Similar to <i>Single Responsibility Principle</i> in SOLID but applied at a macro level (Systems, Modules, Sub-Systems). For example, a payment processing <i>module</i> should only perform payment processing and nothing else (i.e. it should <i>not</i> calculate invoices or bills).<br />
<h2>
DRY - DON'T REPEAT YOURSELF</h2>
Do <i>not</i> implement the same logic twice. Put it in a common module, library, class or function and use it everywhere.<br />
<br />
Factor out common code into helper classes, methods and components. This makes the testing effort more concise and helps track down bugs to a single place in code instead of several repeating code sections.<br />
<h2>
MINIMIZE THE CODE YOU WRITE</h2>
Minimize the amount of code you have to write to solve a problem. The less code there is, the lesser the chance of buggy code. Code Minimization goes beyond DRY in that you may opt to look at alternate design approaches that minimize the amount of code you have to write to begin with. Remember code is a liability! The less code you have to solve the problem, the better. Examples:<br />
<br />
<ul>
<li>Use a well established library or software package to solve the problem instead of writing code to do the same.</li>
<li>Use declarative code instead of imperative code. For example in .Net, instead of using <i>for</i> loops use LINQ.</li>
<li>Instead of using switch/case statements to select a value or action use a table driven approach to look up a value or execute an action (a database table or an in-memory data structure should do the trick).</li>
</ul>
<br />
<h2>
YAGNI - YOU AREN'T GONNA NEED IT</h2>
Do <i>not</i> implement code that is not immediately needed now even if you think you might need it in the future (you probably won't or if you do, you will need something entirely different).<br />
<br />
Don't anticipate features and try to adapt your design or code to the features that are not necessary to complete the stories at hand. The chances are that either the requirements will change over time or the features you anticipate are never really needed. Do the simplest thing that will work.<br />
<h2>
USE DESIGN PATTERNS</h2>
<h2>
<div style="font-size: medium; font-weight: 400;">
When writing code check if there is a well-known design pattern that can be used to make implementation more robust and maintainable. <a href="https://sourcemaking.com/design_patterns" target="_blank">Design Pattern Examples</a></div>
</h2>
<h2>
ORGANIZE YOUR CODE WELL</h2>
Use polymorphism (abstract class + derived classes) to implement specific behaviors instead of conditionals sprinkled all over the code to handle differing behaviors. Use a single switch to instantiate the polymorphic derived class of the desired behavior and have the controlling logic invoke the behavior in a general fashion that is applicable to the entire family of the derived polymorphic classes.<br />
<br />
Keep methods (functions) short and single-purposed. Complex methods should be no longer than 20 lines. Simpler methods should be no longer than 10 lines.<br />
<br />
Do not pass too many parameters into a method. When several parameters must be passed into a method, create a request object that contains the parameters and pass the request object into the method.<br />
<br />
Name the methods purposefully. The name should clearly reflect what the method does. A comment for the method should ideally be unnecessary. Write code that reads like prose. Comments should not be necessary when reading the code. Refactor logic into smaller methods with descriptive names. When reading the main method, the reader should be able deduce the purpose of the helper methods being called and understand what the main method is trying to accomplish without reading the implementation of the helper methods.<br />
<br />
Do not enter who changed the code or the what the ticket or issue number was in code comments. Such information belongs in the source control check-in comments.<br />
<br />
<h2>
GET HELP FROM THE COMPILER</h2>
Use strongly type variables and constructs (generics, for example) to detect problems as early as possible (at compile time instead of runtime). Use enumerations instead of string values. Use named constants instead of string literals. Pay attention to compiler warnings.<br />
<h2>
TESTABILITY</h2>
<h3>
Write testable code</h3>
Structure and implement your code so that it is easily testable. This mind set will naturally help you write code that is loosely coupled and minimizes inter-dependencies. The loose coupling is essential for testing a class or a component in isolation as is necessary when writing Unit Tests.<br />
<h3>
Write automated tests</h3>
By all means write automated Unit Tests. Better yet, take the Test Driven Development (TDD) route. That is, devise and write your tests before you start developing. TDD will greatly help in the design of the system in addition to the more obvious benefit of having a more complete set of automated tests. Having good automated unit tests allow us to refactor our code confidently.<br />
<h3>
Integrate often - Fail fast</h3>
Don't sit on pending changes. Check them in right away to find any incompatible changes. It is better to fail fast and correct the problem earlier in the cycle than to sit on a change and having to figure out why things don't work due to a change you made last week.<br />
<h2>
REFACTORING</h2>
Groom (clean up) code <i>without</i> changing the underlying functionality often. Refactoring is essential for long term maintenance of the code and to facilitate future enhancements.<br />
<br />
Over the time, the code will naturally decay. You will see violations of DRY, Minimize Code and even YAGNI principles. It is imperative to take time to periodically refactor the code to ensure its maintainability over time. Remove and discard dead code. Such code only adds noise to your code base. The lower the noise-to-signal (code) ratio, the better.<br />
<div>
<br /></div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-1731132504178260652019-03-12T10:21:00.000-07:002019-03-12T10:21:04.598-07:00Async calls, why call ConfigureAwait(false)Adding .ConfigureAwait(false) to your async call takes away the overhead of context switching of threads.<br />
<br />
DoSomething(); // on thread 1<br />
<br />
await DoMoreAsync().ConfigureAwait(false); // on thread 2<br />
<br />
DoSomethingElse(); // continues the work on thread 2 (instead of having to switch to thread 1)<br />
<br />
The default for ConfigureAwait is true. But ConfigureAwait(false) is the right thing to do, if the code following the async all does not rely on the context of thread 1 (thread storage of thread 1, for example).<br />
<br />
<br />
<br />Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-12328027832067937602019-03-12T00:35:00.001-07:002019-03-12T00:35:23.225-07:00Async method signature example in C#<br />
<h2>
Interface</h2>
Task<GetDatabaseServersResponse> GetDatabaseServersAsync(GetDatabaseServersRequest request, CancellationToken cancellationToken = default(CancellationToken));<br />
<br />
<h2>
Implementation</h2>
public async Task<GetDatabaseServersResponse> GetDatabaseServersAsync(GetDatabaseServersRequest request, CancellationToken cancellationToken = default(CancellationToken))<br />
{<br />
var list = await _dbContext.DatabaseServer.ToListAsync(cancellationToken);<br />
return new GetDatabaseServersResponse(_mapper.Map<List<DatabaseServerRm>>(list), request.TraceId);<br />
}Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-7220895309122685102019-03-12T00:32:00.001-07:002019-03-12T00:32:34.567-07:00Executing an async method synchronously in C#void <b>NotAnAsyncMethod</b>()<br />
{<br />
try<br />
{<br />
var answer = someAsyncMethod().<b>GetAwaiter</b>().<b>GetResult</b>();<br />
}<br />
catch (Exception ex)<br />
{<br />
// ex is our application's exception instead of aggregate exception<br />
// aggregate exception is thrown if .Wait() and .Result are used instead<br />
}<br />
}Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-91697391914229078182019-02-17T21:02:00.001-08:002019-02-17T21:02:11.550-08:00Creating distinct pairs of values from database tableSELECT * FROM tbl1;<br />
A<br />
B<br />
<br />
SELECT t1.val, t2.val<br />
FROM tbl1 t1, tbl1 t2;<br />
<br />
A A<br />
B A<br />
A B<br />
B B<br />
<br />
SELECT t1.val, t2.val<br />
FROM tbl1 t1, tbl1 t2<br />
WHERE t1.val <> t2.val;<br />
<br />
B A<br />
A B<br />
<br />
SELECT t1.val, t2.val<br />
FROM tbl1 t1, tbl1 t2<br />
WHERE t1.val <> t2.val<br />
AND t1.val < t2.val;<br />
<div>
<br /></div>
<div>
A B</div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-72149207435909726312019-02-02T22:46:00.006-08:002022-06-07T08:19:02.027-07:00Up and running with Angular 7 in 7 minutes<b>1. Install node js</b><br />
<br />
https://nodejs.org/en/download/<br />
<br />
Verify by checking versions as follows.<br />
<br />
node -v<br />
npm -v<br />
<br />
<br />
<br />
<b>2. Install the latest version of Angular CLI</b><br />
<br />
npm install -g @angular/cli<br />
<br />
Verify by checking version.<br />
<br />
ng version<br />
<br /><b>2.1</b> <b>Install specific version of Angular CLI</b><br /><br />
<div>// uninstall previous version of angular cli</div><div>npm uninstall -g @angular/cli</div><div>npm cache clean</div><div><br /></div><div>// install a specific version of angular</div><div>npm i -g @angular/cli@8.3.29</div><div><br /></div><div><br /></div>
<b>3. Install Git</b><br />
<br />
https://git-scm.com/downloads<br />
<br />
// Use <b>without --global</b> if setting these values on project by project basis<br />
git config --global user.email<br />
git config --global user.name<br />
<br />
If a valid email and name is not displayed, set one up using:<br />
<br />
git config --global user.email "email@example.com"<br />
git config --global user.name"Your Name"<br />
<br />
<br />
<br />
<b>4. Verify Sass is installed</b><br />
<br />
Verify by checking version.<br />
<br />
npm sass -v<br />
<div>
<br /></div>
<div>
If not installed:</div>
<div>
<br /></div>
npm install -g sass<br />
<br />
<br />
<br />
<br />
<b>5. Create an Angular app</b><br />
<br />
Change to directory where you would like to create the application.<br />
<br />
ng new helloang<br />
<br />
Routing: Yes<br />
Choose Sass<br />
<br />
<br />
<br />
<b>6. Serve the application</b><br />
<br />
cd helloang<br />
<br />
ng serve --open<br />Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-51647828403945193452018-12-07T09:48:00.000-08:002018-12-07T09:48:05.227-08:00Takeaways and highlights from AWS re:Invent 2018I had an opportunity to attend the seventh installment of AWS re:Invent. It was indeed a large gathering with more than 50,000 in attendance. Despite the size of crowds, the conference was very well run. I was not able to reserve a seat for all the workshops and sessions I was interested in advance but I was able to attend most of these workshops and sessions by queuing up in the walk-up line. Here are some of the takeaways and highlights.<br />
<h2>
Machine Learning was front and center</h2>
AWS provides ML capabilities at three levels of abstraction.<div>
<ol>
<li>Fully managed services such as AWS Rekognition, Polly, Amazon Comprehend (NLP), Alexa, etc. AWS introduced Textract, a smart OCR service.<br /></li>
<li>Managed execution of pre-built or custom ML models. SageMaker fills this role. 150+ machine learning algorithms are being made available in the AWS Marketplace.<br /></li>
<li>Infrastructure for running ML tools such as MXNet, PyTorch, TensorFlow, etc.</li>
</ol>
<ul>
<li>Several new sub-services for SageMaker were announced. For models that require a manual effort to train, AWS introduced SageMaker Ground Truth for classification of data via Mechanical Turk, or other sources. AWS also introduced SageMaker RL which performs training of models through rewards over time. To promote this service, AWS introduced DeepRacer, a fully autonomous 1/18th scale race car driven by reinforcement learning to help developers gain hands-on working knowledge of SageMaker RL. Amazon SageMaker Neo enables machine learning models to train once and run anywhere in the cloud and at the edge with optimal performance.<br /></li>
<li>AWS also announced AWS Inferentia, a new inference chip (yes, a custom-built computer chip) that promises to significantly reduce the time it takes to draw inference from an ML model.<br /></li>
<li>ML Insights works with Amazon QuickSight, a BI Service for interactive dashboards. ML Insights adds ML-powered anomaly detection, ML-powered forecasting, and Auto-narratives (add text descriptions automatically) to QuickSight dashboards.<br /></li>
<li>AWS Personalize is managed service for building and consuming recommendations models. It does the heavy lifting needed to design, train, and deploy a machine learning model under the covers.<br /></li>
<li>AWS RoboMaker provides a robotics development environment for application development (open-source robotics software framework, Robot Operating System,ROS), a robotics simulation service to accelerate application testing, and a robotics fleet management service for remote application deployment, update, and management.</li>
</ul>
<h2>
AWS IoT services matured and can now connect to more things</h2>
<ul>
<li>AWS IoT Core can now ingest data directly, bypassing the MQTT broker, by having the thing publish data to $aws/rules/ruleName topic. This eliminates the additional time and cost of publishing data to an IoT topic before it reaches the rules engine for desired processing.<br /></li>
<li>AWS IoT SiteWise opens up AWS IoT to data from industrial devices. It runs on a gateway that resides in customer's facilities and automates the process of collecting and organizing industrial equipment data.<br /></li>
<li>AWS IoT Events - Managed service to analyze patterns in IoT data respond accordingly.<br /></li>
<li>AWS IoT Things Graph can be used to connect devices and web services to build IoT applications. With this service, one can define interactions between them to build multi-step automation applications.</li>
</ul>
<h2>
Serverless computing saw some important improvements</h2>
<ul>
<li>AWS Lambda now natively supports Ruby.<br /></li>
<li>Lambda now supports custom runtimes (any runtime that can run on Unix) via Lambda Runtime API. C++ and Rust are now supported on Lambda using this new feature. Some other languages that third-parties have enabled on AWS Lambda are Erlang, Elexir, COBOL, and PHP. This feature will certainly encourage migration of legacy code to Lambda.<br /></li>
<li>A new feature of Lambda called Layers allows lambda functions to share code and data. For example, if several Lambda functions use a common library, that library does not need to deployed (duplicated) for each these Lambda functions. Instead, the library can be pulled in from a remote repository.<br /></li>
<li>Step function (orchestration of Lambda functions) can now invoke many AWS managed services (such as DynamoDB, AWS Batch, Amazon SQS, and Amazon SageMaker) directly in a defined flow.<br /></li>
<li>A new service called AWS Serverless Application Repository allows cataloging/discovery/assembly of a serverless application from existing Lambda functions.<br /></li>
<li>Lambda functions can now be placed behind an Application Load Balancer. This allows Lambda functions to be invoked directly via HTTP/HTTPS without having to use the API Gateway.<br /></li>
<li>Firecracker is a lightweight virtualization that is based on KVM. Amazon uses this technology internally to for its AWS Lambda offering as well. According to AWS, this service allows "launching of lightweight micro-virtual machines (microVMs) in non-virtualized environments in a fraction of a second, taking advantage of the security and workload isolation provided by traditional VMs and the resource efficiency that comes along with containers".<br /></li>
<li>AWS App Mesh - For monitoring and controlling communication across microservices on AWS such as ECS, EKS and Kubernetes running on EC2.<br /></li>
<li>API Gateway now supports Web Sockets. For Single Page Apps, live updates from the Server are usually sent over Web Sockets. This makes API Gateway more desirable as a backend for interactive SPAs.<br /></li>
<li>SNS now supports filtering of messages that are published to a given SNS topic. This can help discard undesirable messages at the SNS service level thus reducing traffic to a configured SNS recipient such as AWS Lambda or a microservice.</li>
</ul>
<h2>
Databases and Storage</h2>
Amazon Aurora, a MySQL-based managed database service, was featured prominently in Werner's keynote. Amazon has famously vowed to get rid of all its Oracle databases. I imagine Aurora will replace a good number of these databases.<br /><ul>
<li>Amazon Aurora added a Global database feature that is designed for applications with a global footprint. It allows a single Aurora database to span multiple AWS regions, with fast replication to enable low-latency global reads and disaster recovery from region-wide outages. I imagine one of the main motivations for adding this feature was to match Microsoft Azure Cosmos Database's globally distributed storage model.<br /></li>
<li>Amazon DynamoDB added ACID-compliant transactions across multiple tables in a given AWS region. This is important for applications that need to store data reliably across multiple tables in a single transaction. DynamoDB also added an On-demand pricing model where the application does not need upfront capacity planning (read/write capacity units).<br /></li>
<li>Amazon Timestream is a new database offering optimized for storing timestream data and is more cost effective than other storage options such as RDS. This is an attractive option for storing large amount of streaming data such as Telemetry data from IoT devices.<br /></li>
<li>Amazon had previously introduced AWS Glue to discover and catalog structured and unstructured data to aid in building of a Data Lake. Amazon has now introduced AWS Lake Formation, that sits on top of AWS Glue, and makes the job of configuring data sources and governance of the source data much simpler.<br /></li>
<li>S3 added intelligent tiering which automatically moves data to different pricing/availability tiers of S3 based on S3 object access patterns.<br /></li>
<li>AWS Transfer for SFTP is new fully managed SFTP service S3. This allows access to data stored in S3 buckets through SFTP protocol.<br /></li>
<li>Amazon introduced Amazon FSx for Lustre, a fully managed file system for use with Lustre, a file system used for large-scale cluster computing. Similarly, Amazon FSx for Windows File Server delivers a managed Windows file system (supports SMB, NTFS and AD) for use with workloads on Windows Server.</li>
</ul>
<h2>
Amazon finally gets into the Blockchain game</h2>
Two Blockchain related services were announced.<br /><ol>
<li>Amazon Managed Blockchain is a fully managed service that makes it easy to create and manage scalable Blockchain networks using popular open source frameworks Hyperledger Fabric & Ethereum.<br /></li>
<li>Amazon Quantum Ledger Database (QLDB) is a purpose-built ledger database that provides a complete and verifiable history of application data changes. The database is append only/immutable (can't be edited) and cryptographically verified (to ensure contents have not been tampered).</li>
</ol>
<h2>
Finally, there were new offerings in the area of DevOps and Security</h2>
<ul>
<li>AWS CodeDeploy now supports Blue/Green deployments for AWS Fargate and Amazon ECS.<br /></li>
<li>AWS Security Hub enables AWS customers to centrally view and manage security alerts and automate compliance checks within and across AWS accounts.<br /></li>
<li>AWS Control Tower helps create and maintain secure, well-architected multi-account AWS environments with respect to configuration of organizations, federated access, centralized logging, IAMs auditing, and workflows for provisioning new accounts.<br /></li>
<li>AWS Well-Architected Tool can review state of workloads and compare them to the latest AWS architectural best practices.<br /></li>
<li>AWS Outposts (later in 2019) - An on-premise hardware offering developed jointly by Amazon and VMWare. It is fully managed, maintained, and supported by AWS to deliver access to the latest AWS services on customer's site. It brings native AWS services, infrastructure, and operating models to virtually any data center, co-location space, or on-premises facility.<br /></li>
</ul>
Well, that's all for this year. I believe we are nowhere near utilizing the full potential of AI, Machine Learning, and IoT data. I have no doubt we will see many more outstanding innovations in these areas in the near future. We are now well-beyond dynamic websites (Web 1.0) and mobile computing (Web 2.0). Warp speed to AI, ML and IoT (Web 3.0).</div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-15013309865678401622018-10-20T12:17:00.000-07:002018-10-20T12:51:50.589-07:00Java Threading<div>
Implement a class that implements IRunnable (requires run() method</div>
<div>
<br />
<div>
// This code can reside inside or outside the class that implements IRunnable</div>
<div>
Thread thread = new Thread(<instance of class that implements IRunnable)</div>
</div>
<br />
<div>
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<div style="font-weight: 400; margin: 0px;">
thread.start(); // executes the run() method</div>
<div style="font-weight: 400; margin: 0px;">
<br /></div>
<div style="font-weight: 400; margin: 0px;">
public class SomeProcess implements Runnable{</div>
<div style="font-weight: 400; margin: 0px;">
<br /></div>
<div style="font-weight: 400; margin: 0px;">
Thread runner;</div>
<div style="font-weight: 400; margin: 0px;">
<br /></div>
<div style="font-weight: 400; margin: 0px;">
SomeProcess (){</div>
<div style="font-weight: 400; margin: 0px;">
if (runner == null){</div>
<div style="font-weight: 400; margin: 0px;">
runner = new Thread(this); // look for Run method in this class</div>
<div style="font-weight: 400; margin: 0px;">
runner.start(); // executes the Run method</div>
<div style="font-weight: 400; margin: 0px;">
}</div>
<div style="font-weight: 400; margin: 0px;">
}</div>
<div style="font-weight: 400; margin: 0px;">
<br /></div>
<div style="font-weight: 400;">
public void Run (){</div>
<div style="font-weight: 400;">
Thread thisThread = Thread.currentThread();</div>
<div style="font-weight: 400;">
<br /></div>
<div style="font-weight: 400;">
// thread terminates when Run() ends</div>
<div style="font-weight: 400;">
}</div>
<div style="font-weight: 400;">
<br /></div>
<b>OR</b><br />
<div style="font-weight: 400;">
<br /></div>
<div style="font-weight: 400; margin: 0px;">
// set this.runner to null to terminate the thread by setting </div>
<div style="font-weight: 400; margin: 0px;">
// this.runner to null from anywhere else</div>
<div style="font-weight: 400; margin: 0px;">
// </div>
<div style="font-weight: 400; margin: 0px;">
public void Run (){</div>
<div style="font-weight: 400; margin: 0px;">
Thread thisThread = Thread.currentThread();</div>
<div style="font-weight: 400; margin: 0px;">
while (runner == thisThread){</div>
<div style="font-weight: 400; margin: 0px;">
<br /></div>
<div style="font-weight: 400; margin: 0px;">
}</div>
<div style="font-weight: 400; margin: 0px;">
// thread terminates when Run() ends</div>
<div style="font-weight: 400; margin: 0px;">
}</div>
<div style="font-weight: 400; margin: 0px;">
<br /></div>
<div style="font-weight: 400; margin: 0px;">
}<br />
<br />
<h3>
Creating with an anonymous inner class</h3>
new Runnable() {<br />
public void run(){<br />
}}<br />
}<br />
<h3>
Creating with a Closure</h3>
There is only required method for Runnable so we can define as Closure/lambda<br />
Runnable runner = () -> { // code for Run method }</div>
</div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-43369480137769928602018-10-20T12:07:00.000-07:002018-10-20T12:07:04.580-07:00Java Data StructuresBitSet -for representing binary data (indexed 0, 1 values)<br />
<br />
ArrayList<br />
<br />
Stack<br />
<br />
HashMap - Dictiionary, key-value pairs<br />
<br />
Generics - Create typed type structures<br />
ArrayList<String><br />
HashMap<String, Float>Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-49298660395634583062018-10-20T12:01:00.000-07:002018-10-20T12:01:03.492-07:00Java Access Modifiers<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-E-RNtY0RMsQ/W8t7T-xJH_I/AAAAAAAANUA/dI6y6suoLCgkz1wy7CnYbY42xqIC8XOhACLcBGAs/s1600/JavaAccessModifiers.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="664" data-original-width="1600" height="132" src="https://3.bp.blogspot.com/-E-RNtY0RMsQ/W8t7T-xJH_I/AAAAAAAANUA/dI6y6suoLCgkz1wy7CnYbY42xqIC8XOhACLcBGAs/s320/JavaAccessModifiers.jpg" width="320" /></a></div>
<br />Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-40584291239096064782018-10-03T12:33:00.002-07:002018-10-03T12:33:48.916-07:00Aws IoT - Device ConnectivityDevices connect to Aws IoT core using one of the supported protocols. Data from the device is transported to the Aws IoT as JSON document.<br />
<h2>
Protocols</h2>
The message broker supports the use of the MQTT protocol to publish and subscribe and the HTTPS protocol to publish. The message broker also supports MQTT over the WebSocket protocol.<br />
<ul>
<li>MQTT, Client Certificate, 8883, 443</li>
<li>HTTP, Client Certificate, 8443</li>
<li>HTTP, SigV4, 443</li>
<li>MQTT + WebSocket, SigV4, 443</li>
</ul>
<h2>
Connectivity from Device using Client Certificate</h2>
<h3>
Resources on Device</h3>
<ol>
<li>x509 Certificate specific to the device (establishes device identity; equivalent to username in classic authentication). An X.509 certificate is a document that is used to prove ownership of a public key embedded in the cert. CA creates a certificate and signs it with a private key. Anyone can now validate your device certificate by checking its digital signature with the CA’s public key. (.pem.cer file)</li>
<li>Private key corresponding to device's x509 (for signing communication)</li>
<li>Root certificate for Aws IoT server (to verify the authenticity of certificate returned by Aws IoT to the device; Answers question: Am I talking to the real Aws IoT Server?). On Aws IoT Button, this certificate is already baked in. (.pem file)</li>
<li>Client connectivity to Internet: WIFI SSID, password</li>
<li>Aws IoT Server endpoint (region-specific, endpoint for multiple devices). For example: abc.iot.us-east-1.amazonaws.com</li>
</ol>
<ol>
</ol>
<h3>
Resources on Aws IoT Server</h3>
<div>
<ol>
<li>x509 Certificate specific to the device with an associated Certificate Id.</li>
</ol>
<div>
Each connected device is represented as thing. It has unique arn. For example:<br />arn:aws:iot:us-east-1:995042574424:thing/iotbutton_G030MD045XXXXX</div>
</div>
<h3>
Communication Flow</h3>
<div>
Two step process.</div>
<div>
<br /></div>
<div>
1) Establish secure communication between the device and Aws IoT server. This is just like connecting to a secure website. The Server sends it's certificate to Client. Client wants to make sure it is talking to the real AWS IoT. Client verifies that server cert is authentic by using the AWs IoT Service root certificate present on the device. The public key that’s embedded in the root certificate is used to validate the digital signature on the Server provided certificate. Client and Server then negotiate and use a shared secret to encrypt communication.</div>
<div>
<br /></div>
<div>
2) Next device identifies itself to Aws IoT server. Device sends a copy of its device certificate to the server. Device calculates a hash over the data sent to Server with its private key and sends it as the digital signature. AWS IoT is now in possession of the devices’ public key (which was in the device certificate) and the digital signature. It uses the device’s public key to check the accuracy of the digital signature. By using the unique identifier of the certificate, it knows exactly which device is establishing a MQTT session. From then on, all messages between the device and AWS IoT are secured using the shared secret (for efficiency).</div>
<h2>
Aws Resource Access</h2>
<div>
Aws resources that are allowed to be accessed by a device are specified by associating a policy with Device's certificate on the Aws IoT Server.</div>
<br />
For example, the following policy publishes the data received from a device to an SNS topic.<br />
<br />
{<br />
"Version": "2012-10-17",<br />
"Statement": [<br />
{<br />
"Action": "iot:Publish",<br />
"Effect": "Allow",<br />
"Resource": "arn:aws:iot:us-east-1:995042574424:topic/iotbutton/G030MD045XXXXX"<br />
}<br />
]<br />
}<br />
<br />
1. Messages are published to a device specific SNS topic<br />
<br />
2. Rules engine picks up the message from the SNS topic and then publishes the data to configured destination (under Act tab).<br />
<div>
<h3>
Data Flow</h3>
</div>
<div>
Data received from device by the Message Broker on Aws IoT Server and can be routed to another Aws resource by Aws IoT Server's Rule engine.</div>
<div>
<ol>
<li>DynamoDB</li>
<li>Kinesis</li>
<li>Lambda</li>
<li>S3</li>
<li>SNS</li>
<li>SQS</li>
</ol>
</div>
<br />Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-74092366517892239712018-04-23T12:03:00.001-07:002018-04-23T12:25:03.981-07:00React app with Redux and Redux Observables<h2>
Technologies</h2>
<div>
<ul>
<li>React js (for UI)</li>
<li>Redux (for state management; actions and reducers that set state)</li>
<li>React-Redux (for connecting Redux to React; redux actions and arbitrary properties that can be set as properties of the component; Provider component makes the store available to all components)</li>
<li>Redux Observable (for linking RxJS to Redux; applyMiddleware to redux store; takes care of RxJS subscriptions and un-subscribe)</li>
<li>RxJS (Reactive programming based on observables)</li>
</ul>
</div>
<h2>
Packages</h2>
yarn add redux react-redux rxjs redux-observable<br />
<br />
// rxjs requires tslib<br />
yarn add tslib<br />
<h2>
The Idea</h2>
<ul>
<li>Redux Action is dispatched</li>
<li>Received by the Reducer</li>
<li>Since there is redux observable middle-ware applied, the action is then received by the Epic (redux observable action handler)</li>
<li>Epic is now free to either handle that action or not based on the action.type</li>
<li>Epic can fire an entirely new action that is then received by the Reducer</li>
<li>Which in turn may possibly be handled by another Epic (or not)</li>
</ul>
<h2>
Data Retrieval Flow</h2>
<div>
Epics (Redux observables) are very good at handling asynchronous operations, errors, and mapping results.</div>
<div>
<ul>
<li>An redux action is invoked (for example, by clicking a button)</li>
<li>Action is handled by the reducer (which can possibly place a loading message in the store, which in turn my be displayed by react component to the user)</li>
<li>The same action can then be optionally handled by an Epic (redux observables middleware)</li>
<li>The Epic can perform the asynchronous data fetch operation (ajax, for example)</li>
<li>When finished, Epic can produce another action with the data retrieved</li>
<li>That action is then handled by the reducer, that may remove the loading message from the store and set retrieved value in the store.</li>
<li>The retrieved value in the store may then be reflected in the react component</li>
</ul>
</div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-19908400299502892782018-04-22T09:20:00.002-07:002018-04-22T09:20:40.360-07:00Git Help<pre>
usage: git [--version] [--help] [-C <path>] [-c name=value]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
These are common Git commands used in various situations:
start a working area (see also: git help tutorial)
clone Clone a repository into a new directory
init Create an empty Git repository or reinitialize an existing one
work on the current change (see also: git help everyday)
add Add file contents to the index
mv Move or rename a file, a directory, or a symlink
reset Reset current HEAD to the specified state
rm Remove files from the working tree and from the index
examine the history and state (see also: git help revisions)
bisect Use binary search to find the commit that introduced a bug
grep Print lines matching a pattern
log Show commit logs
show Show various types of objects
status Show the working tree status
grow, mark and tweak your common history
branch List, create, or delete branches
checkout Switch branches or restore working tree files
commit Record changes to the repository
diff Show changes between commits, commit and working tree, etc
merge Join two or more development histories together
rebase Reapply commits on top of another base tip
tag Create, list, delete or verify a tag object signed with GPG
collaborate (see also: git help workflows)
fetch Download objects and refs from another repository
pull Fetch from and integrate with another repository or a local branch
push Update remote refs along with associated objects
'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
</pre>Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-55450785904101668782018-02-23T13:46:00.002-08:002018-02-23T13:57:16.145-08:00Imperative vs Object-Oriented vs Functional Programming Style<b>Same program written in three programming styles.</b><br />
<h2>
<b>IMPERATIVE PROGRAMMING STYLE</b></h2>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-upuqY8yYZ1M/WpCLanlnHFI/AAAAAAAAKL0/Hes7jOd-pdE6Q3t68D0biBymNVgkFzk1gCLcBGAs/s1600/imperative.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="571" data-original-width="609" height="600" src="https://3.bp.blogspot.com/-upuqY8yYZ1M/WpCLanlnHFI/AAAAAAAAKL0/Hes7jOd-pdE6Q3t68D0biBymNVgkFzk1gCLcBGAs/s640/imperative.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-s6GyTIE7efo/WpCMxqokgVI/AAAAAAAAKMY/UJB7ptaTQQIIxxNSUbAgGnFsOL1DlsxbACLcBGAs/s1600/imperative_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="100" data-original-width="343" height="93" src="https://4.bp.blogspot.com/-s6GyTIE7efo/WpCMxqokgVI/AAAAAAAAKMY/UJB7ptaTQQIIxxNSUbAgGnFsOL1DlsxbACLcBGAs/s320/imperative_1.png" width="320" /></a></div>
<br />
<br />
<h2>
<b>OBJECT-ORIENTED PROGRAMMING STYLE</b></h2>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-ZWt2KCfTfsc/WpCLdFDtTJI/AAAAAAAAKL4/Vu2ZLX9JwRUapEiigLHp40A8okxbXZuhACLcBGAs/s1600/oo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="524" data-original-width="603" height="556" src="https://1.bp.blogspot.com/-ZWt2KCfTfsc/WpCLdFDtTJI/AAAAAAAAKL4/Vu2ZLX9JwRUapEiigLHp40A8okxbXZuhACLcBGAs/s640/oo.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-xw_LH4VOesw/WpCM_EiPldI/AAAAAAAAKMc/WSpUpEicht0EC6fLmUunZrNrJSK31u5uwCLcBGAs/s1600/oo_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="113" data-original-width="345" height="104" src="https://3.bp.blogspot.com/-xw_LH4VOesw/WpCM_EiPldI/AAAAAAAAKMc/WSpUpEicht0EC6fLmUunZrNrJSK31u5uwCLcBGAs/s320/oo_1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<b><br /></b></div>
<h2>
<b>FUNCTIONAL PROGRAMMING STYLE</b></h2>
<div>
<b><br /></b>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-ZQoZYi0TQKQ/WpCLhvLvmzI/AAAAAAAAKL8/Vtu26auehYQx4o_vBFFPey54HY6baqW6wCLcBGAs/s1600/fn.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="477" data-original-width="580" height="524" src="https://4.bp.blogspot.com/-ZQoZYi0TQKQ/WpCLhvLvmzI/AAAAAAAAKL8/Vtu26auehYQx4o_vBFFPey54HY6baqW6wCLcBGAs/s640/fn.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-DsygkyE_MLI/WpCNEDXxCsI/AAAAAAAAKMg/aJId5Yr0RzkPwfFS1W_7BvXk7tb6fqShgCLcBGAs/s1600/fn_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="111" data-original-width="341" height="104" src="https://4.bp.blogspot.com/-DsygkyE_MLI/WpCNEDXxCsI/AAAAAAAAKMg/aJId5Yr0RzkPwfFS1W_7BvXk7tb6fqShgCLcBGAs/s320/fn_1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br /></div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-55506338805738342572018-02-23T13:25:00.003-08:002018-02-23T13:25:46.288-08:00Function Closure<br />
A function closure contains a function and the environment the function is referenced in. The referencing environment may contain variables that are not local to the function but are nonetheless accessible to the function code. These non-local variables are called free variables or upvalues.<br />
<br />
// example of function closure for Inner()<br />
function Outer(){<br />
var upvalue = 1<br />
<br />
function Inner(){<br />
// upvalue is available here & part of function closure<br />
// for Inner()<br />
var funcVar = 2<br />
}<br />
}<br />
<div>
<br /></div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-47345914659856042412017-12-09T18:39:00.000-08:002018-02-28T10:08:23.696-08:00Setting up a simple HTTP Server for local web development<h2>
watch-http-server</h2>
It works similarly to http-server but automatically reloads the webpage when it changes on disk. This is very useful during developement.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">npm install -g watch-http-server</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>See: <a href="https://www.npmjs.com/package/watch-http-server" target="_blank">watch-http-server</a><br />
<br />
<br />
1. Install NodeJS from https://nodejs.org<br />
<br />
2. Install <span style="font-family: "courier new" , "courier" , monospace;">watch-http-server or </span><span style="font-family: "courier new" , "courier" , monospace;">http-server</span> npm package<br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">npm install -g watch-http-server</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">or</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">npm install -g http-server</span><br />
<br />
3. From command line, change to the directory containing your static web files (e.g. html, javascript, css etc) in the command line window, e.g:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">cd \temp\website</span><br />
<br />
4. Start the server from the website directory with following command line command.<br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">watch-http-server -o -a localhost</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">or</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">http-server</span><br />
<br />
<br />
Or run it with more more options<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">watch-http-server --help</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">C:\Users\srazzaq>watch-http-server --help</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">usage: http-server [path] [options]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">options:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -p Port to use [8080]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -a Address to use [0.0.0.0]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -d Show directory listings [true]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -i Display autoIndex [true]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -e --ext Default file extension if none supplied [none]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -s --silent Suppress log messages from output</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> --cors Enable CORS via the 'Access-Control-Allow-Origin' header</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -o Open browser window after staring the server</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -c Cache time (max-age) in seconds [3600], e.g. -c10 for 10 seconds.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> To disable caching, use -c-1.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> -S --ssl Enable https.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -C --cert Path to ssl cert file (default: cert.pem).</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> -K --key Path to ssl key file (default: key.pem).</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> -h --help Print this list and exit.</span><br />
<br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">5</span>. The watch-http-server will start and print the local http address where the website can be reached. It is typically http://localhost:8080. Open your browser and go to the address http://localhost:8080 and you should see the index file in your web site directory from Step 3.<br />
<br />
<h2>
</h2>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-31187334281963539262017-10-25T21:29:00.004-07:002017-10-29T19:25:49.955-07:00Getting started with React in 5 minutes<br />
<h2>
Development Environment Setup</h2>
1. Install <a href="http://node.js/">node.js</a>. What you really need is npm that is installed as part of node.js.<br />
<br />
2. Install create-react-app npm module globally. This npm modules contains scripts that set up a new app, ready for further development.<br />
<br />
<b>npm install -g create-react-app</b><br />
<br />
3. Create a folder where you want to create your react apps<br />
<b><br /></b>
<b>C:\> md react</b><br />
<b>C:\> cd react</b><br />
<b>C:\react></b><br />
<br />
4. Create an app<br />
<br />
<b>C:\react> create-react-app hello-react</b><br />
<br />
5. Change to your new application directory<br />
<br />
<b>C:\react> cd hello-react</b><br />
<br />
6. Now you can run the dev version of your app.<br />
<b><br /></b>
<b>npm start</b><br />
<br />
7. Build production optimized version of your app in the build subfolder.<br />
<br />
<b>npm run build</b><br />
<br />
8. To run the production version, npm install a static server (need to do just once)<br />
<br />
<b>npm install -g serve</b><br />
<br />
9. Run the production version of the app<br />
<br />
<b>serve -s build</b><br />
<b><br /></b>
10. To manage all the configuration scripts yourself (permanent for the app; cannot be reverted).<br />
<b><br /></b>
<b>npm run eject</b><br />
<h2>
React-friendly Editors, IDEs and Tools</h2>
<div>
<ul>
<li>Visual Studio Code</li>
<li>Sublime Text</li>
<li>WebStorm</li>
<li>Chrome Extension for React</li>
</ul>
<h2>
Tools under the hood</h2>
<div>
React development environment uses the following tools.</div>
<div>
<ul>
<li>Babel - Transpiler to convert ES6 JavaScript to ES5 for a wider Web Browser compatibility</li>
<li>webpack module bundler - To create a single bundle of js from multiple files</li>
<li>express - http server for dev</li>
<li>serve-static - To serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express</li>
<li>eslint - static analysis of code</li>
</ul>
</div>
<h2>
Advanced State Management Module (optional)</h2>
<div>
<ul>
<li>Redux</li>
<li>Use redux-logger middleware for viewing state changes</li>
</ul>
</div>
</div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-51727093290344921512017-10-25T13:53:00.001-07:002017-10-25T13:57:52.349-07:00npm - Node Package Managernpm manages JavaScript packages (source code for modules).<br />
<br />
npm gets the package from the repository at <a href="https://www.npmjs.com/" target="_blank">https://www.npmjs.com/</a><br />
<br />
npm is installed as part of nodeJs installation. Think of nodeJs as the runtime for npm.<br />
<h2>
Install npm</h2>
Install the latest version of <a href="https://nodejs.org/en/" target="_blank">nodeJs</a>. npm is installed as part of nodeJs.<br />
<h2>
Initialize npm config file</h2>
Go the application directory.<br />
<br />
npm init<br />
<br />
Creates package.json that contains packages installed by npm.<br />
<h2>
Install a package</h2>
npm install <packagename> --save<br />
<br />
Creates a node_modules folder for the module source code.<br />
--save makes an entry for the module in Package.json<br />
<h2>
Package.json</h2>
Package.json keeps track of all packages installed (their dependencies).<br />
<br />
npm modules can re-installed/refreshed by running:<br />
<br />
npm install<br />
<br />
We can create named scripts in the package.json<br />
<br />
script {<br />
"start" : "<command line>"<br />
<br />
The script can then be invoked as:<br />
npm run <namedscript><br />
<br />
npm run build<br />
npm run start<br />
<br />
This is useful for builds and for starting the application.<br />
<h2>
App code sharing</h2>
When sharing code that uses npm packages, do NOT share node_modules folder. Simply share your js code and package.json. Running the the following command installs all the packages specified in package.json.<br />
<br />
npm install<br />
<h2>
Global vs Local Modules</h2>
<div>
npm modules are usually installed local to an application (folder). This is preferred to avoid any breaking changes to modules.</div>
<div>
<br /></div>
<div>
Modules can be installed globally. This is usually done for dev tools that are utilized for multiple projects. For example, nodemon module that detects and restarts an application (web server) may be installed globally. nodeman re-executes a script or restarts the web server when underlying source code is changed.</div>
<br />
npm install -g nodeman<br />
<br />
To find the location of the global npm module folder:<br />
npm root -g<br />
<br />
To remove a global module.<br />
npm remove -g nodeman<br />
<h2>
Useful Commands</h2>
<h3>
Check npm version</h3>
npm -v<br />
npm --version<br />
<h3>
Get help</h3>
npm<br />
npm help<br />
// overview<br />
npm help npm<br />
<h3>
Initialize npm</h3>
npm init<br />
<br />
// answer yes to all questions<br />
npm init --yes <br />
<br />
// set / get / delete initialization defaults<br />
npm config set <value-name-from-package.json> "default value"<br />
<br />
npm config get <value-name-from-package.json><br />
<br />
npm config delete <value-name-from-package.json><br />
<h3>
Install/Uninstall modules</h3>
// install module and update package.json<br />
npm install lodash --save<br />
<br />
// development only package install<br />
npm install <package-name> --save-dev<br />
<br />
// install a module globally<br />
npm install -g <packagename><br />
<br />
// get (refresh) ALL packages in package.json<br />
npm install<br />
<br />
// get production-only packages in package.json<br />
npm install --production<br />
<br />
// uninstall a package - delete from module folder and package.json<br />
// remove and rm are synonyms for uninstall<br />
npm uninstall <packagename><br />
<br />
To remove a global module.<br />
npm remove -g <packagename><br />
<br />
// install a specific version of a package<br />
npm install <packagename>@version --save<br />
<br />
// update to the latest version<br />
npm update <packageversion><br />
<br />
If the version specified in the package starts with:<br />
<br />
^1.2.3 Update to the latest minor version. Retain the major version.<br />
~1.2.3 Update to the latest patch. Retain the major and minor version<br />
* Update to the latest version<br />
<br />
To specify update to a specify version of module, enter the specific version and do not precede the version with any of the characters above. Example: "1.2.3"<br />
<br />
1.2.3<br />
1 is major version<br />
2 is minor version<br />
3 is patch version<br />
<h3>
Listing installed modules</h3>
// list all packages and their dependencies<br />
npm list<br />
<br />
// list top level packages only<br />
npm list --depth 0Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-28593221376616914242017-10-25T13:30:00.002-07:002017-10-25T13:58:45.589-07:00Executing JavaScript Code<h2>
JavaScript can be run in a Web Browser</h2>
For example, in Google Chrome<br />
<br />
1) Start Browser<br />
<br />
2) Press F12 to open Developer tools<br />
<br />
3) JavaScript code can be entered and run from either the following tabs.<br />
<br />
<ul>
<li>Console</li>
<li>Sources | Snippets</li>
</ul>
<br />
<h2>
JavaScript can be run from Command Line (Terminal)</h2>
1) Install <a href="https://nodejs.org/en/" target="_blank">nodeJs</a><br />
<br />
2) Create a js file, for example app.js<br />
<br />
3) Run the js file<br />
<br />
node app.js<br />
<h2>
Website hosted JavaScript REPL</h2>
See: <a href="https://jsfiddle.net/" target="_blank">https://jsfiddle.net/</a>Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-10688342984113465462017-10-21T09:14:00.005-07:002017-10-21T10:46:24.246-07:00JavaScript ES2015 ES6 Module SupportES6 lets you <i>natively</i> define and use modules.<br />
<br />
Since most Web Browsers do <i>not</i> currently support this feature, the code must be transpiled into ES5 using a tool such as <a href="https://babeljs.io/repl/" target="_blank">Babel</a>. This must occur at build time as a development step.<br />
<br />
The code is transpiled into AMD or CommonJS module format by the tool. The HTML source then references RequireJS/SystemJS that is used by the Browser to load the modules in the depedency order at runtime.<br />
<br />
To avoid use of a runtime module loader (for efficiency sake), the code can be bundled using bundlers such as Webpack (AMD module format) or Browserify (commonjs module format; commonly used to package nodejs code for use in a Browser) as a development step. The development step takes the transpiled source code and creates one or more bundled js files that contains code in the module dependency order (hence eliminating the need for a runtime module loader).<br />
<h2>
Module Export Syntax</h2>
<h3>
Export functions inline</h3>
// somefile.js<br />
export function doSomething(doWhat){<br />
}<br />
<br />
export function printResults(){<br />
}<br />
<br />
// do not export a private function<br />
function privateHelper(){<br />
}<br />
<br />
// export a variable<br />
export var pi = 3.142<br />
<h3>
Export public functions with a declaration</h3>
// somefile.js<br />
function doSomething(doWhat){<br />
}<br />
<br />
function printResults(){<br />
}<br />
<br />
function privateHelper(){<br />
}<br />
<br />
// export a variable<br />
var pi = 3.142<br />
<br />
// we are renaming printResults to print when exporting<br />
// we are also exporting a variable (can do the same for classes)<br />
// privateHelper is not a part of the Api<br />
export { doSomething, printResults as print, pi}<br />
<h3>
Specify Default Export</h3>
// somefile.js<br />
export function doSomething(doWhat){<br />
}<br />
<br />
// make printResults the default function exported out of this module<br />
export <b>default</b> function printResults(){<br />
}<br />
<br />
function privateHelper(){<br />
}<br />
<br />
// export a variable<br />
export var pi = 3.142<br />
<h2>
Module Import Syntax</h2>
// import all public functions from the module<br />
// methods can be invoked on extModule, e.g. extModule.printResults()<br />
import * as extModule from './somefile.js'<br />
<br />
// selective import of functions<br />
// functions are invoked as usual e.g. printResults()<br />
import {doSomething, printResults} as extModule from './somefile.js'<br />
<br />
// selective import of functions with an alias<br />
// function are invoked with its alias e.g. print()<br />
import {doSomething, printResults as print} as extModule from './somefile.js'<br />
<br />
// import the default function as print()<br />
import print from './somefile.js'<br />
<br />
// import the default function and another function<br />
// print() is exported as default, also import doSomething function<br />
import print, {doSomething} from './somefile.js'Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-4511970798539091692017-10-20T13:43:00.001-07:002017-10-21T10:47:43.767-07:00JavaScript Module Formats and Loaders<h2>
JavaScript Module Formats</h2>
How JavaScript code (function) is structured into a module that can be loaded by Module loader at runtime in correct dependency order. This is just a convention followed in plain js to form Modules.<br />
<ul>
<li>AMD Format (Asynchronous Module Dependency) - primarily used in Browser js since it has the advantage of being async loading. define function is used to load dependencies.</li>
<li>CommonJS Format - more prevalent in server (nodeJs) apps. require function is used to load dependencies.</li>
<li>Universal Module Definition (UMD) - Has both the features of AMD and CommonJS</li>
<li>System.register - Specific to SystemJS module loader</li>
<li>ES2015 - Native support in ES6 - Need to use something like Babel to use in current browsers</li>
</ul>
<h2>
JavaScript Module Loaders</h2>
JavaScript libraries that load modules (specified in supported format) while honoring the dependencies.<br />
<ul>
<li>RequireJS Module Loader can load modules in AMD Format</li>
<li>SystemJS Module Loader can load modules in CommonJS Format</li>
</ul>
<br />
<br />
<br />Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-66900675533381309482017-10-19T07:21:00.001-07:002017-10-20T13:24:02.254-07:00JavaScript Modules<h2>
Singleton Pattern</h2>
Immediately Invoked Function Expression (IIFE) returns an object that contains references to the public API of the module.<br />
<br />
displayName function-scoped variable serves as the data member and retains its value as a result of function closure.<br />
<br />
var myModule = (function(){<br />
var displayName<br />
<br />
function setName(name){<br />
displayName = name<br />
}<br />
<br />
function printName(){<br />
console.log('Hello ' + displayName)<br />
}<br />
<br />
return{<br />
setName : setName,<br />
printName : printName<br />
}<br />
})()<br />
<br />
myModule.setName('Bob')<br />
myModule.printName()<br />
<br />
<span style="background-color: #cccccc;">Hello Bob</span><br />
<h2>
Function Constructor Pattern</h2>
MyModule is a reference to a function closure. It is <i>not</i> immediately invoked. It still returns an object that contains references to the public API of the module. We can create multiple instances of this function using the new keyword. Each instance maintains its own state (displayName in this case).<br />
<br />
var MyModule = function(){<br />
var displayName<br />
<br />
function setName(name){<br />
displayName = name<br />
}<br />
<br />
function printName(){<br />
console.log('Hello ' + displayName)<br />
}<br />
<br />
return{<br />
setName : setName,<br />
printName : printName<br />
}<br />
}<br />
<br />
myModule = new MyModule<br />
yourModule = new MyModule<br />
myModule.setName('Jack')<br />
yourModule.setName('Diane')<br />
myModule.printName()<br />
yourModule.printName()<br />
<br />
<span style="background-color: #cccccc;">Hello Jack</span><br />
<span style="background-color: #cccccc;">Hello Diane</span><br />
<br />
// Same as above but using prototype for efficiency<br />
// (function definitions are not duplicated for each instance)<br />
var MyModule = function(){<br />
var displayName<br />
}<br />
<br />
MyModule.prototype.setName = function setName(name){<br />
this.displayName = name<br />
}<br />
<br />
MyModule.prototype.printName = function printName(){<br />
<span style="white-space: pre;"> </span>console.log('Hello ' + this.displayName)<br />
}<br />
<span style="white-space: pre;"> </span><br />
myModule = new MyModule<br />
yourModule = new MyModule<br />
myModule.setName('Jack')<br />
yourModule.setName('Diane')<br />
myModule.printName()<br />
yourModule.printName()<br />
<br />
<span style="background-color: #cccccc;">Hello Jack</span><br />
<span style="background-color: #cccccc;">Hello Diane</span><br />
<br />Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.comtag:blogger.com,1999:blog-5437932071029458618.post-11606993853632177512017-10-17T09:04:00.001-07:002017-10-17T13:25:35.531-07:00JavaScript ES6 ES2015 New Feature OverviewJavaScript adds more useful language features in ES6 (ES2015).<br />
<br />
New features can be used right now while being backwards compatible with older browsers by using Babel js which transpiles ES6 to ES5. Babel js can be used in a build step for a js project.<br />
<a href="https://babeljs.io/" target="_blank">https://babeljs.io/</a><br />
<br />
ES6 be used on the backend (nodeJs) and front end (React, etc.).<br />
<h2>
Destructuring</h2>
Take an object or an array and rip it apart into variables.<br />
<br />
// object<br />
var o = {<br />
p1: 1,<br />
p2: 2<br />
}<br />
var {p1, p2} = o<br />
console.log (p1, p2)<br />
<br />
<span style="background-color: #eeeeee;">1 2</span><br />
<br />
// array<br />
var a = [1, 2]<br />
var [v1, v2] = a<br />
console.log (v1, v2)<br />
<br />
<span style="background-color: #eeeeee;">1 2</span><br />
<br />
// function arguments<br />
var o = {<br />
arg1: 1,<br />
arg2: 2<br />
}<br />
<br />
var fn = ({arg2, arg3, arg1}) => {<br />
console.log(arg1, arg2, arg3)<br />
}<br />
<br />
fn(o)<br />
<br />
<span style="background-color: #eeeeee;">1 2 undefined</span><br />
<h2>
Spread Operator</h2>
function fn(a1, a2, a3){<br />
console.log(a2)<br />
}<br />
<br />
var arr = [1, 2, 3]<br />
fn(...arr)<br />
<br />
<span style="background-color: #eeeeee;">2</span><br />
<br />
var arr = [1, 2, 3, 4, 5]<br />
var [first, ...theRest] = arr<br />
console.log(first)<br />
console.log(theRest)<br />
<br />
<span style="background-color: #eeeeee;">1</span><br />
<span style="background-color: #eeeeee;">(4) [2, 3, 4, 5]]</span><br />
<br />
var ar1 = [4, 5]<br />
var ar2 = [1, 2, 3]<br />
<br />
var ar = [...ar2, ...ar1, 6]<br />
console.log(ar)<br />
<span style="background-color: #eeeeee;"><br /></span>
<span style="background-color: #eeeeee;">(6) [1, 2, 3, 4, 5, 6]</span><br />
<h2>
Template Strings</h2>
// use back tick and ${varName}<br />
var name = "Slim Shady"<br />
var formattedStr = `My name is<br />
${name}`<br />
<br />
console.log(formattedStr)<br />
<br />
<span style="background-color: #eeeeee;">My name is</span><br />
<span style="background-color: #eeeeee;">Slim Shady</span><br />
<h2>
Block Scoping</h2>
// var scoping is at function level<br />
//<span style="white-space: pre;"> </span>No matter where a variable is defined in a function,<br />
//<span style="white-space: pre;"> </span>the variable is hoisted to the top of the function<br />
// let<br />
//<span style="white-space: pre;"> </span>Limits scope of a variable to a block (e.g. if and loop stmt blocks)<br />
//<span style="white-space: pre;"> </span>Use let EVERYWHERE instead of var<br />
<br />
let v = 1<br />
<br />
if (true){<br />
let v = 2<br />
console.log(v)<br />
}<br />
<br />
console.log(v)<br />
<br />
<span style="background-color: #eeeeee;">2</span><br />
<span style="background-color: #eeeeee;">1</span><br />
<h2>
Constants</h2>
// const to define a variable that can be assigned to only once<br />
// However, an object assigned to a const CAN be mutated<br />
// user const everywhere if you prefer immutable objects in JavaScript<br />
<br />
const c = 1<br />
c = 2<br />
console.log(c)<br />
<br />
<span style="background-color: #eeeeee;">Uncaught TypeError: Assignment to constant variable.</span><br />
<h2>
Arrow Functions</h2>
var fn =(a, b) => {<br />
return a + b<br />
}<br />
console.log(fn(1, 2))<br />
<br />
// implict return<br />
var fn = (a, b) => a + b<br />
console.log(fn(2, 3))<br />
<br />
<span style="background-color: #eeeeee;">3</span><br />
<span style="background-color: #eeeeee;">5</span><br />
<br />
const total = [0, 1, 2, 3].reduce((sum, value) => sum + value, 1)<br />
console.log(total)<br />
<br />
<span style="background-color: #eeeeee;">7</span><br />
<br />
// arrow functions automatically set lexical context<br />
//<span style="white-space: pre;"> </span>may not be desired when writing callbacks for some libraries,<br />
//<span style="white-space: pre;"> </span>such as jQuery where this is bound to jQuery library<br />
var o = {<br />
<span style="white-space: pre;"> </span>data: 1,<br />
<span style="white-space: pre;"> </span>print : function(){<br />
<span style="white-space: pre;"> </span>console.log(this.data)<br />
<span style="white-space: pre;"> </span>}<br />
}<br />
o.print()<br />
<br />
<span style="background-color: #eeeeee;">1</span><br />
<br />
// must bind to this in order to access the data<br />
var o = {<br />
<span style="white-space: pre;"> </span>data: 1,<br />
<span style="white-space: pre;"> </span>print : function(){<br />
<span style="white-space: pre;"> </span>setTimeout(function() {<br />
<span style="white-space: pre;"> </span>console.log(this.data)<br />
<span style="white-space: pre;"> </span>}.bind(this), 100)<br />
<span style="white-space: pre;"> </span>}<br />
}<br />
o.print()<br />
<span style="background-color: #eeeeee;"><br /></span>
<span style="background-color: #eeeeee;">1</span><br />
<br />
// Alternate: use arrow function, no need to bind this<br />
var o = {<br />
<span style="white-space: pre;"> </span>data: 1,<br />
<span style="white-space: pre;"> </span>print : function(){<br />
<span style="white-space: pre;"> </span>// automatically binds the this context<br />
<span style="white-space: pre;"> </span>setTimeout(() => {<br />
<span style="white-space: pre;"> </span>console.log(this.data)<br />
<span style="white-space: pre;"> </span>}, 100)<br />
<span style="white-space: pre;"> </span>}<br />
}<br />
o.print()<br />
<br />
<span style="background-color: #eeeeee;">1</span><br />
<br />
var numbers = [1,2,3,4,5]<br />
var strings = numbers.map(n => n.toString())<br />
console.log(strings)<br />
<br />
<span style="background-color: #eeeeee;">(5) ["1", "2", "3", "4", "5"]</span><br />
<br />
// How to use 'this' in a timer function (without arrow functions),<br />
// whose context is Global context, not the function context<br />
// this.val is scoped to the function<br />
// define'that' variable in the function closure to keep a reference to 'this'<br />
// to be accessed by setTimeout function that runs in global scope<br />
function fn() {<br />
var that = this<br />
this.val = 0<br />
<br />
setTimeout(function inc(){<br />
// can't use this.val because this function is in global scope<br />
that.val++<br />
}, 0)<br />
<br />
this.print = function() {<br />
console.log(that.val)<br />
}<br />
}<br />
<br />
var f = new fn()<br />
<br />
setTimeout(() => f.print(), 100)<br />
<br />
<span style="background-color: #eeeeee;">1</span><br />
<br />
// arrow functions are lexically scoped to the block they are contained<br />
// now we no longer have to preserve 'this' in 'that' variable<br />
function fn() {<br />
this.val = 0<br />
<br />
setTimeout(() => {<br />
this.val++<br />
}, 0)<br />
<br />
this.print = function() {<br />
console.log(this.val)<br />
}<br />
}<br />
<br />
var f = new fn()<br />
<br />
setTimeout(() => f.print(), 100)<br />
<br />
<span style="background-color: #eeeeee;">1</span><br />
<h2>
Classes</h2>
class Base{<br />
constructor(){<br />
this.data = 1 <br />
}<br />
<br />
fn(){<br />
console.log('Base ' + this.data)<br />
}<br />
}<br />
<br />
class Derived extends Base{<br />
<span style="white-space: pre;"> </span>constructor(){<br />
super()<br />
}<br />
fn(){<br />
console.log('Derived ' + this.data)<br />
}<br />
}<br />
<br />
var base = new Base()<br />
base.fn()<br />
<br />
var derived = new Derived()<br />
derived.fn()<br />
<br />
<span style="background-color: #eeeeee;">Base 1</span><br />
<span style="background-color: #eeeeee;">Derived 1</span><br />
<br />
<h2>
Module System</h2>
Replaces 'require' library<br />
<br />
Export (module1.js):<br />
module.exports.pi = () => 3.142<br />
module.exports.multidentity = () => 1<br />
<br />
// entire module export is replaced with this function<br />
export default function(){<br />
}<br />
// export entire module<br />
export default {<br />
}<br />
<br />
To export function:<br />
export function fn(){<br />
}<br />
<br />
To export variable:<br />
export const pi = 22/7<br />
<br />
To import:<br />
import module1 from "module1"<br />
<br />
To import (with destructuring, selectively pull what you need):<br />
import {pi, multidentity} from "module1"<br />
<br />
To import with an alias:<br />
import {pi, multidentity as one} from "module1"<br />
console.log(one)<br />
<br />
Async (Generator function) Function<br />
<br />
async function() {<br />
<span style="white-space: pre;"> </span>var data = await $.get(url)<br />
<span style="white-space: pre;"> </span>console.log(data)<br />
}<br />
<div>
<br /></div>
Sal Razzaqhttp://www.blogger.com/profile/09170402220701159195noreply@blogger.com