SonarQube Tips

Make sure this cross-domain message is being sent to the intended domain

HTML5 adds the ability to send messages to documents served from other domains. According to the specification:

Authors should not use the wildcard keyword ( *) in the targetOrigin argument in messages that contain any confidential information, as otherwise there is no way to guarantee that the message is only delivered to the recipient to which it was intended.
To mitigate the risk of sending sensitive information to a document served from a hostile or unknown domain, this rule raises an issue each time Window.postMessage is used.

Noncompliant Code Example

1
2
var myWindow = document.getElementById('myIFrame').contentWindow;
myWindow.postMessage(message, "*"); // Noncompliant; how do you know what you loaded in 'myIFrame' is still there?

Solution

This rule detects only if a method postMessage is invoked on an object with a name containing window in it. Source code: PostMessageCheck.java. To bypass it, just assign your contentWindow object into different one, like this:

1
2
var content = this.elem.contentWindow;
content.postMessage('your message', window.location.origin);

Using Angular Library

Overview - Angular Library

Using Angular Library
Environment: angular v8.2; node.js v12

Create

You can create an Angular library within an existing application. e.g. lib name is my-lib. Commands:

1
ng generate library my-lib`

Build

1
ng build my-lib

Tips

How to Promote M4rix offers with traffic

M4Trix

M4trix offers a plethora of private offers, ranging from health and beauty to E-commerce, covering the full spectrum of payout models. We control the entire flow from supply to local delivery and customer support, allowing us to deliver unmatched performance for your traffic.

  • Selection of offers is available worldwide. We specialize in exclusive “never seen before” in the industry geos, with an emphasis on hyper-profitable countries such as the EMENA area. Our affiliates experience instant profit testing in these non-saturated markets.
  • Smart Link Technology dynamically matches each click with the most enhanced intelligence to maximize your performance. Languages, currencies, creatives, processors and cross platform performance are optimized in near real-time.
  • Focus on the personal relationships with each of our affiliates, providing a full suite of resources and a close one on one relationship to make you profitable. Localized advertorials flow, market analysis and creatives are standard assets we provide for each campaign. Already running high volume? Take the red pill and double your EPC.

Tracking M4trix Offers

If using a different tracker, simply copy and paste this onto the end of your Offer’s URL.

1
cid={cid}

Postback url, appends

1
cid={cid}&payout={payout}

From M4Trix

A Private Affiliate Network opening up our own offers.

Everything in the M4TRIX is 100% owned and controlled by us, which allows to offer higher performance and payouts for our Affiliates.

Every network will claim the “Higher EPC” and “Higher Payout” thing, realistically speaking, the more intermediary there is, the more people need to get paid and the less there is left for the affiliate at the end of the chain. When dealing with the M4TRIX Network, you are talking directly with the advertiser, you are the only one in the chain!

We own and control multiple offers ranging from High Scale Worldwide E-Commerce to Health & Beauty in Exclusive Geos.

Inside the M4TRIX you’ll get the choice between the classic Pay Per Sale model or our Cash On Delivery offers (Pay Per Lead) in Private Geos such as North Africa and the Middle East. We are the only advertiser in the space, these offers and geos can not be found anywhere else.

The M4TRIX aim to revolutionize the industry with a more transparent relationship and access to new untapped markets. We focus on the personal relationship, we provide localized Pre-Sell and resources to get you started and profitable.

Our payment terms are Weekly Net4. Faster payouts are available for Hyper Affiliate generating $100.000+ per day.

Register Now and Experience the M4TRIX!

How to use Affiliate Pixels and Tracking in Getcake

Affiliate Pixels and Tracking

This article will cover the following:

  • Affiliate Pixels

  • Tokens in Affiiate Pixels

  • Restricting Affiliate Pixels

Affiliate Pixels
Affiliates pixels are placed at the campaign level and can be placed directly by the affiliate through the Affiliate Portal. Alternatively, the pixel can be placed by an admin employee in the Admin Portal as well.

Placing pixels in the Admin Portal
Zoom:

In the Admin portal you can place an affiliate pixel on the Campaign card > Home tab > Pixels sub-tab.

You can view a list of tokens by using the hover menu for the Setup tab > Show Tokens. The full list of available tokens includes the following:

1
2
3
4
5
6
7
8
9
10
11
Affiliate ID: #affid#
Offer ID: #oid#
Campaign ID: #campid#
Creative ID: #cid#
Sub ID 1: #s1#
Sub ID 2: #s2#
Sub ID 3: #s3#
Sub ID 4: #s4#
Sub ID 5: #s5#
Request ID: #reqid#
UDID: #udid#

Conversion Pixels Only:

Transaction ID: #tid#
Lead ID: #leadid#
Price (Affiliate Payout): #price#
Click IP: #sourceip#
Conversion IP: #ip#
Conversion UNIX timestamp: #utcunixtime#
Conversion timestamp: #sourcedate# (ie. 2013-11-12T13:04:27.5670000)

Placing pixels in the Affiliate Portal
Zoom:
Affiliate pixels are placed in the Offer card > Testing & Tracking tab. Here, your Affiliate will enter their test link and their pixel. A list of tokens is available on the left-hand side, and clicking on them will place the corresponding token wherever your cursor is located.

Once placed, CAKE will display these pixels in the Affiliate tab > Pending > Pixels section.

There is an optional alert associated with Affiliate pixel placements - the ‘Pixel Was Placed on Campaign’ to alert you that an affiliate has placed a pixel. Such an alert allows you to verify the proper formatting or the type of pixel once it is placed to help proactively avoid tracking errors. For example, if your advertiser places your postback or server pixel, your affiliate needs to use a postback as well. For this reason, we have a setting to restrict the type of pixel your affiliate places.

Restricting Affiliate Pixels
In order to prevent the chance that an affiliate will place a web-based pixel (iframe / javascript / image) in error, CAKE has created a setting to restrict affiliates to placing postbacks only. You can enable this across the board for every affiliate and campaign in Setup > Settings > Affiliate Portal Settings > Affiliate Permissions. The specific setting is the first in the section to ‘Only Allow Affiliate Postbacks’.

With no further action, the Affiliate will no longer be able to place any pixel other than a postback through the Affiliate Portal. Every campaign will now have a warning icon stating that this setting has been enabled.

NOTE: If you have a postback placed with your Advertiser, placing a non-postback even in the admin will not function.

If you want to pick and choose where and when to apply this feature, you can do that as well. Without the global setting, every offer will include a option (which goes away with the Global Setting enabled) for “Postbacks Only”. Enabling this checkbox on the offer card will immediately pop up the warning icons on the campaigns for that offer.

Tracking Settings

Section 1: Where to access Tracking Settings

To access your Tracking Settings click on the main Setup tab > Settings sub tab > Tracking Settings

Section 2: General Settings

Cookie Domain: The cookie domain is used for either affiliate tracking links, conversion pixels or as a POST URL for server posting into CAKE. This domain is decided upon during the onboarding process.

Session Regeneration Minutes: Duplicate clicks/conversions will not be counted if they occur within the specified time period. Users may override at the offer level.

Global Redirect: The default URL where a customer is redirect on invalid/inactive links, after all Upsell and Redirect paths have been exhausted and when no Thank You Link is present.

Paid Redirects: If selected, campaign redirects will be paid. Users may override at the affiliate level on the Affiliate card.

Encrypt Links: If enabled, all generated unique links and click/impression pixels will be encrypted to hide identifying source information.

Base Tracking Domain Redirect: The URL where a customer is redirected on clicks to a base tracking domain sans affiliate/query string info. If left blank, the Global Redirect will be used.

Don’t pay for Bot Traffic on CPC: If enabled, conversions will not be recorded from bot traffic on all CPC campaigns. Clicks will be recorded but without payment. If disabled, conversions will be recorded from my traffic on all CPC campaigns. Clicks will be recorded and paid for.

Don’t pay for Bot Traffic on CPM: If enabled, conversions will not be recorded from bot traffic on CPM campaigns. Impressions will still be recorded sans payment.

Enable Events: Enable this option to add event tracking options.

Grouped Offers: If enabled, this will turn on Grouped Offers (1:Many tracking)

Child Click Inherits Parent SubIDs: When enabled the values of s2-5 on the child offer’s click will be inherited from the parent offer’s click (note: sub ids from the child offer will be ignored). When disabled, only s1 will be inherited and s2-5 will be taken from the child offer’s click.

Cap Percentage Threshold: This allows CAKE users to override the default cap threshold of 90%, to a different percentage. Example: setting this to 50% will trip the alert when 50% of the cap is reached.

Section 3: Global Pixels & Postbacks

Global Pixels: Enables pixel placement at the affiliate, offer and global level.

Global Pixel: Pixels placed here will fire on all offers unless otherwise modified at the offer or affiliate level.

Postback URL: This URL will fire on all offers unless otherwise modified at the offer or affiliate level.

Postback Delay (ms): The delay (in milliseconds) before firing the global postback upon any conversion.

Fire Global Pixel By Default: If enabled, all new offers will fire global pixel by default.

Fire Pixel on Non Paid Conversions: If enabled, the global pixel fires on non paid conversions.

Section 4: Conversions

Pending Conversions: If enabled, all conversions will be sent to Queue.

Default Approved: Sets the default disposition for auto approved conversions.

Default Pending: Sets the default pending disposition for all conversions set for review at the campaign or affiliate level.

Default Rejected: Sets the default disposition for auto rejected conversions.

Conversion Cap Behavior: This setting allows you to customize how incoming conversions are dealt with once a conversion cap is hit. Any new or existing offers not assigned an explicit conversion cap behavior will be defaulted to this conversion cap behavior.

Conversion Behavior On Redirect: This setting allows you to customize how incoming conversions are dealt with when any redirect criteria is met (e.g. Inactive Affiliate, Expired offer), expect for conversion caps whose default behavior can be individually customized above. Any new or existing offers will be defaulted to this conversion behavior on redirect.

Section 5: Original Campaign Settings

Original Campaign by Offer Contract: Account for offer contract in original/non-original campaign creation.

Original Campaign by Media Type: Account for media type in original/non-original campaign creation.

Top 10 Affiliate Marketing Programs For 2020

StudioPress Affiliate Website

StudioPress is another rather a niche but very worthwhile affiliate to pursue if you have the digital presence audience. They create responsive, adaptable and highly customisable WordPress hosting and themes, that extend the function and accessibility of WordPress fluidly.

Studiopress Affiliate Marketing Website

Pros

Another product that sells itself. Most WordPress users take one look at StudioPress’ work and fall in love with what they can achieve with it. Which makes your job easy.
Generous payouts, that grow the more you refer (to a point). 35% per theme sale and a minimum of $75 per site sale made can add up if your audience is interested.
Cons

Still a niche product. It requires an audience that wants to establish themselves online. No matter what the niche, that’s a demand that’s growing. But it’s still not for everyone… Yet.

CJ Affiliate Publisher’s Program

CJ Affiliate is a platform that knows what they’re talking about. They’ve been in the Affiliate Marketing industry since 1998 and that expertise just shines through in every aspect of what they do. With products in every niche, you’d be hard-pressed to find fault with them.

CJ Affiliate Platform

Pros

One of the largest Affiliate Networks. When you’ve been in business as long as CJ Affiliate has, it’s hard for other programs to rival them in size.
A network you can rely on. 19 years in business doesn’t make them infallible, but it does show they can expertly adapt. You can rely on them to continue to do so.
Cons

There’s a pretty scrutinous application process. You don’t get to succeed for almost 20 years without high standards, so this is to be expected.

11. ConvertKit Affiliate Program

ConvertKit is a leading email marketing platform. With ideology based around being customisable and uniquely fitting to every user, you can understand why they come highly recommended by many top names in the email marketing industry.

ConvertKit Affiliate Program

Pros

If your audience uses email marketing, they will love ConvertKit. It’s just a fact – if you’re in that space, ConvertKit easily reaches every need of it that you can conceive.
No cut-off of the affiliate revenue. As long as your affiliate’s account is active and paying – you’re getting paid. There’s absolutely no point where they’ll cut you off.
Cons

Not everyone uses email marketing. That’s just the reality. Some of your audiences will not be using it, so this isn’t a great affiliate for you.
Every commission takes 30 days to confirm. As they have a 30-day, no questions asked, refund policy – they can’t credit you with the commission until 30 days have passed.

1. Fiverr Affiliate Program

Fiverr Affiliates Commission Structure
Fiverr Affiliates: Commission Structure
Promote the world’s largest marketplace for digital services - Fiverr. From whiteboard explainer videos to Wordpress and logo design, earn up to $150 for every first-time buyer with their dynamic CPA model. Get paid to drive traffic, it’s that easy.

With over 3 million digital services available, 250 unique categories and a gig purchased every 4-seconds, anyone can easily find a relevant service to promote from Fiverr’s marketplace.

Start earning with Fiverr - Join Now ⟶

Maximize your affiliate potential with Fiverr’s new stores for affiliates. As an affiliate, there are some things you do the best. You might be the best content writer, the best marketer, or the best videographer in your industry, but… there are some tasks you clearly struggle with. You may need help developing creative copy for Facebook posts or crafting that unique thumbnail image to increase clicks on Youtube, the list goes on and on.

To save you time and increase your affiliate success, Fiverr has created the ultimate set of stores to support your affiliate efforts with premier talent. Those stores include the most relevant and best performing gigs from their top sellers in variety of categories: Web or Blog, YouTube, Facebook and Instagram.

ClickFunnels Affiliate Program

Want to have your dream car paid for? Simply refer 100 customers to ClickFunnels and your new car could arrive sooner than you think.

“Get Just 100 New ClickFunnels Users…And We’ll [ClickFunnels] Cover The Payments On YOUR Dream Car!”

ClickFunnels Affiliates Dream Car Promotion
As an affiliate you also have the ability to earn huge recurring commissions on all of their top level products and services. The ClickFunnels Affiliate Program offers a generous 40% recurring commissions on all sales you send their way. On a starter plan that equates to $38.80 every month (MRR*), per customer, for life!

Wealthy Affiliate Program

Wealthy Affiliate
Wealthy Affiliate Community Dashboard
Turn your passion into a thriving online business with Wealthy Affiliates. Simply follow their proven process easy to use tools to launch a website, attract visitors, and most importantly, earn revenue. Wealthy Affiliate was created by Kyle and Carson, who in 2005, launched the Wealthy Affiliate platform to help other people succeed online. Since then Wealthy Affiliate community has grown to over 800,000 internet entrepreneurs.

Launch your online business, then make money sharing your secret with others. Wealthy Affiliate has one of the most engaging affiliate programs available online — earn consistent revenue by simply referring others to the community. Average commission $100 per premium signup.

Media.net

Media.net ambassador program
Tap into one of the largest pools of advertisers in the world and let Media.net ads maximize your monetization. Monetize every single impression by seamlessly with Contextual ads, Display ads, and customizable Native ads- no additional coding required. Plus, join their ambassador program to earn 10% commission on all referral earnings for the first 12 months.

Leadpages

Leadpages affiliate program
Join the Leadpages Affiliate Partner Program a start promoting their suite of lead generation tools, which have helped hundreds of thousands of entrepreneurs create sustainable small businesses online. Earn 30% recurring commission on all sales you generate, for as long as your referrals remain customers, including renewals and upgrades of their Leadpages plan.

Shopify Affiliate Program

Shopify
Earn 200% commission based on the price of the subscription your referral signs up to. Shopify is one of the most well-known eCommerce platforms, website builders and point of sales software providers in the the world. Earn an average of $58 for each paid signup who uses your unique referral link, and $2000 for each Plus referral.

Vue or Angular in 2020

You should first make a clear decision as to whether you need a single-page-application (SPA) or if you’d rather take a multi-page approach.

Angular

Angular is a TypeScript-based Javascript framework. Developed and maintained by Google, it’s described as a “Superheroic JavaScript MVW Framework”. Angular (also “Angular 2+”, “Angular 2” or “ng2”) is the rewritten, mostly incompatible successor to AngularJS (also “Angular.js” or “AngularJS 1.x”). While AngularJS (the old one) was initially released in October 2010, it is still getting bug-fixes, etc. — the new Angular (sans JS) was introduced in September 2016 as version 2.

Vue

The greatest benefit of Vue is it’s absence of pedigree. It is fresh and has little baggage. It has been learning from the mistakes and successes of React & Angular. The way we see it, Vue is lightweight & easy to learn.
It has got some fairly basic docs but they do a good job, and while there isn’t a great deal to learn compared to angular – this is a good thing as it’s deceptively powerful. PageKit, Python China are two of of the projects using Vue among many. Here’s the list. Also, it has two way data binding facility like Angular and Virtual DOM like React.

Compare

Long-term support & migrations

Regarding Angular, there is a blog post about versioning and releasing Angular starting with the v2 release. There will be one major update every six months, and there will be a deprecation period of at least six months (two major releases). There are some experimental APIs marked in the documentation with shorter deprecation periods. There is no official announcement yet, but according to this article, the Angular team has announced long-term-support versions starting with Angular 4. Those will be supported for at least one year beyond the next major version release. This means Angular 4 will be supported until at least September 2018 with bug-fixes and important patches. In most cases, updating Angular from v2 to v4 is as easy as updating the Angular dependencies. Angular also offers a guide with information as to whether further changes are needed.

The update process for Vue 1.x to 2.0 should be easy for a small app — the developer team has asserted that 90% of the APIs stayed the same. There is a nice upgrade-diagnostic migration-helper tool working on the console. One developer noted that the update from v1 to v2 was still no fun in a big app. Unfortunately, there is no clear (public) roadmap about the next major version or information on plans for LTS versions.

One more thing: Angular is a full framework and offers a lot of things bundled together. React is more flexible than Angular, and you will probably wind up using more independent, unsettled, fast-moving libraries — this means that you need to take care of the corresponding updates and migrations on your own. It could also be a detriment if certain packages are no longer maintained or some other package becomes the de facto standard at some point.

Javascript Error Handling

Error handling, “try..catch”

No matter how great we are at programming, sometimes our scripts have errors. They may occur because of our mistakes, an unexpected user input, an erroneous server response, and for a thousand other reasons.

Usually, a script “dies” (immediately stops) in case of an error, printing it to console.

But there’s a syntax construct try..catch that allows to “catch” errors and, instead of dying, do something more reasonable.

The “try..catch” syntax

The try..catch construct has two main blocks: try, and then catch:

1
2
3
4
5
6
7
8
9
try {

// code...

} catch (err) {

// error handling

}

It works like this:

  1. First, the code in try {...} is executed.
  2. If there were no errors, then catch(err) is ignored: the execution reaches the end of try and goes on, skipping catch.
  3. If an error occurs, then try execution is stopped, and the control flows to the beginning of catch(err). The err variable (can use any name for it) will contain an error object with details about what happened.

So, an error inside the try {…} block does not kill the script: we have a chance to handle it in catch.

Let’s see examples.

  • An errorless example: shows alert (1) and (2):

    run
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    try {

    alert('Start of try runs'); // *!*(1) <--*/!*

    // ...no errors here

    alert('End of try runs'); // *!*(2) <--*/!*

    } catch(err) {

    alert('Catch is ignored, because there are no errors'); // (3)

    }
  • An example with an error: shows (1) and (3):

    run
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    try {

    alert('Start of try runs'); // *!*(1) <--*/!*

    *!*
    lalala; // error, variable is not defined!
    */!*

    alert('End of try (never reached)'); // (2)

    } catch(err) {

    alert(`Error has occurred!`); // *!*(3) <--*/!*

    }
header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
For `try..catch` to work, the code must be runnable. In other words, it should be valid JavaScript.

It won't work if the code is syntactically wrong, for instance it has unmatched curly braces:

```js run
try {
{{{{{{{{{{{{
} catch(e) {
alert("The engine can't understand this code, it's invalid");
}
```

The JavaScript engine first reads the code, and then runs it. The errors that occur on the reading phase are called "parse-time" errors and are unrecoverable (from inside that code). That's because the engine can't understand the code.

So, `try..catch` can only handle errors that occur in the valid code. Such errors are called "runtime errors" or, sometimes, "exceptions".
header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
If an exception happens in "scheduled" code, like in `setTimeout`, then `try..catch` won't catch it:

```js run
try {
setTimeout(function() {
noSuchVariable; // script will die here
}, 1000);
} catch (e) {
alert( "won't work" );
}
```

That's because the function itself is executed later, when the engine has already left the `try..catch` construct.

To catch an exception inside a scheduled function, `try..catch` must be inside that function:
```js run
setTimeout(function() {
try {
noSuchVariable; // try..catch handles the error!
} catch {
alert( "error is caught here!" );
}
}, 1000);
```

Error object

When an error occurs, JavaScript generates an object containing the details about it. The object is then passed as an argument to catch:

1
2
3
4
5
try {
// ...
} catch(err) { // <-- the "error object", could use another word instead of err
// ...
}

For all built-in errors, the error object has two main properties:

name
Error name. For instance, for an undefined variable that’s "ReferenceError".
message
Textual message about error details.

There are other non-standard properties available in most environments. One of most widely used and supported is:

stack
Current call stack: a string with information about the sequence of nested calls that led to the error. Used for debugging purposes.

For instance:

run untrusted
1
2
3
4
5
6
7
8
9
10
11
12
13
try {
*!*
lalala; // error, variable is not defined!
*/!*
} catch(err) {
alert(err.name); // ReferenceError
alert(err.message); // lalala is not defined
alert(err.stack); // ReferenceError: lalala is not defined at (...call stack)

// Can also show an error as a whole
// The error is converted to string as "name: message"
alert(err); // ReferenceError: lalala is not defined
}

Optional “catch” binding

[recent browser=new]

If we don’t need error details, catch may omit it:

1
2
3
4
5
try {
// ...
} catch { // <-- without (err)
// ...
}

Using “try..catch”

Let’s explore a real-life use case of try..catch.

As we already know, JavaScript supports the JSON.parse(str) method to read JSON-encoded values.

Usually it’s used to decode data received over the network, from the server or another source.

We receive it and call JSON.parse like this:

run
1
2
3
4
5
6
7
8
9
let json = '{"name":"John", "age": 30}'; // data from the server

*!*
let user = JSON.parse(json); // convert the text representation to JS object
*/!*

// now user is an object with properties from the string
alert( user.name ); // John
alert( user.age ); // 30

You can find more detailed information about JSON in the info:json chapter.

If json is malformed, JSON.parse generates an error, so the script “dies”.

Should we be satisfied with that? Of course not!

This way, if something’s wrong with the data, the visitor will never know that (unless they open the developer console). And people really don’t like when something “just dies” without any error message.

Let’s use try..catch to handle the error:

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let json = "{ bad json }";

try {

*!*
let user = JSON.parse(json); // <-- when an error occurs...
*/!*
alert( user.name ); // doesn't work

} catch (e) {
*!*
// ...the execution jumps here
alert( "Our apologies, the data has errors, we'll try to request it one more time." );
alert( e.name );
alert( e.message );
*/!*
}

Here we use the catch block only to show the message, but we can do much more: send a new network request, suggest an alternative to the visitor, send information about the error to a logging facility, … . All much better than just dying.

Throwing our own errors

What if json is syntactically correct, but doesn’t have a required name property?

Like this:

run
1
2
3
4
5
6
7
8
9
10
11
12
let json = '{ "age": 30 }'; // incomplete data

try {

let user = JSON.parse(json); // <-- no errors
*!*
alert( user.name ); // no name!
*/!*

} catch (e) {
alert( "doesn't execute" );
}

Here JSON.parse runs normally, but the absence of name is actually an error for us.

To unify error handling, we’ll use the throw operator.

“Throw” operator

The throw operator generates an error.

The syntax is:

1
throw <error object>

Technically, we can use anything as an error object. That may be even a primitive, like a number or a string, but it’s better to use objects, preferably with name and message properties (to stay somewhat compatible with built-in errors).

JavaScript has many built-in constructors for standard errors: Error, SyntaxError, ReferenceError, TypeError and others. We can use them to create error objects as well.

Their syntax is:

1
2
3
4
5
let error = new Error(message);
// or
let error = new SyntaxError(message);
let error = new ReferenceError(message);
// ...

For built-in errors (not for any objects, just for errors), the name property is exactly the name of the constructor. And message is taken from the argument.

For instance:

run
1
2
3
4
let error = new Error("Things happen o_O");

alert(error.name); // Error
alert(error.message); // Things happen o_O

Let’s see what kind of error JSON.parse generates:

run
1
2
3
4
5
6
7
8
try {
JSON.parse("{ bad json o_O }");
} catch(e) {
*!*
alert(e.name); // SyntaxError
*/!*
alert(e.message); // Unexpected token b in JSON at position 2
}

As we can see, that’s a SyntaxError.

And in our case, the absence of name is an error, as users must have a name.

So let’s throw it:

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let json = '{ "age": 30 }'; // incomplete data

try {

let user = JSON.parse(json); // <-- no errors

if (!user.name) {
*!*
throw new SyntaxError("Incomplete data: no name"); // (*)
*/!*
}

alert( user.name );

} catch(e) {
alert( "JSON Error: " + e.message ); // JSON Error: Incomplete data: no name
}

In the line (*), the throw operator generates a SyntaxError with the given message, the same way as JavaScript would generate it itself. The execution of try immediately stops and the control flow jumps into catch.

Now catch became a single place for all error handling: both for JSON.parse and other cases.

Rethrowing

In the example above we use try..catch to handle incorrect data. But is it possible that another unexpected error occurs within the try {...} block? Like a programming error (variable is not defined) or something else, not just this “incorrect data” thing.

For example:

run
1
2
3
4
5
6
7
8
9
10
let json = '{ "age": 30 }'; // incomplete data

try {
user = JSON.parse(json); // <-- forgot to put "let" before user

// ...
} catch(err) {
alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined
// (no JSON Error actually)
}

Of course, everything’s possible! Programmers do make mistakes. Even in open-source utilities used by millions for decades – suddenly a bug may be discovered that leads to terrible hacks.

In our case, try..catch is meant to catch “incorrect data” errors. But by its nature, catch gets all errors from try. Here it gets an unexpected error, but still shows the same "JSON Error" message. That’s wrong and also makes the code more difficult to debug.

Fortunately, we can find out which error we get, for instance from its name:

run
1
2
3
4
5
6
7
try {
user = { /*...*/ };
} catch(e) {
*!*
alert(e.name); // "ReferenceError" for accessing an undefined variable
*/!*
}

The rule is simple:

Catch should only process errors that it knows and “rethrow” all others.

The “rethrowing” technique can be explained in more detail as:

  1. Catch gets all errors.
  2. In the catch(err) {...} block we analyze the error object err.
  3. If we don’t know how to handle it, we do throw err.

In the code below, we use rethrowing so that catch only handles SyntaxError:

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let json = '{ "age": 30 }'; // incomplete data
try {

let user = JSON.parse(json);

if (!user.name) {
throw new SyntaxError("Incomplete data: no name");
}

*!*
blabla(); // unexpected error
*/!*

alert( user.name );

} catch(e) {

*!*
if (e.name == "SyntaxError") {
alert( "JSON Error: " + e.message );
} else {
throw e; // rethrow (*)
}
*/!*

}

The error throwing on line (*) from inside catch block “falls out” of try..catch and can be either caught by an outer try..catch construct (if it exists), or it kills the script.

So the catch block actually handles only errors that it knows how to deal with and “skips” all others.

The example below demonstrates how such errors can be caught by one more level of try..catch:

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function readData() {
let json = '{ "age": 30 }';

try {
// ...
*!*
blabla(); // error!
*/!*
} catch (e) {
// ...
if (e.name != 'SyntaxError') {
*!*
throw e; // rethrow (don't know how to deal with it)
*/!*
}
}
}

try {
readData();
} catch (e) {
*!*
alert( "External catch got: " + e ); // caught it!
*/!*
}

Here readData only knows how to handle SyntaxError, while the outer try..catch knows how to handle everything.

try..catch..finally

Wait, that’s not all.

The try..catch construct may have one more code clause: finally.

If it exists, it runs in all cases:

  • after try, if there were no errors,
  • after catch, if there were errors.

The extended syntax looks like this:

1
2
3
4
5
6
7
*!*try*/!* {
... try to execute the code ...
} *!*catch*/!*(e) {
... handle errors ...
} *!*finally*/!* {
... execute always ...
}

Try running this code:

run
1
2
3
4
5
6
7
8
try {
alert( 'try' );
if (confirm('Make an error?')) BAD_CODE();
} catch (e) {
alert( 'catch' );
} finally {
alert( 'finally' );
}

The code has two ways of execution:

  1. If you answer “Yes” to “Make an error?”, then try -> catch -> finally.
  2. If you say “No”, then try -> finally.

The finally clause is often used when we start doing something and want to finalize it in any case of outcome.

For instance, we want to measure the time that a Fibonacci numbers function fib(n) takes. Naturally, we can start measuring before it runs and finish afterwards. But what if there’s an error during the function call? In particular, the implementation of fib(n) in the code below returns an error for negative or non-integer numbers.

The finally clause is a great place to finish the measurements no matter what.

Here finally guarantees that the time will be measured correctly in both situations – in case of a successful execution of fib and in case of an error in it:

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let num = +prompt("Enter a positive integer number?", 35)

let diff, result;

function fib(n) {
if (n < 0 || Math.trunc(n) != n) {
throw new Error("Must not be negative, and also an integer.");
}
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}

let start = Date.now();

try {
result = fib(num);
} catch (e) {
result = 0;
*!*
} finally {
diff = Date.now() - start;
}
*/!*

alert(result || "error occurred");

alert( `execution took ${diff}ms` );

You can check by running the code with entering 35 into prompt – it executes normally, finally after try. And then enter -1 – there will be an immediate error, and the execution will take 0ms. Both measurements are done correctly.

In other words, the function may finish with return or throw, that doesn’t matter. The finally clause executes in both cases.

header
1
2
3
Please note that `result` and `diff` variables in the code above are declared *before* `try..catch`.

Otherwise, if we declared `let` in `try` block, it would only be visible inside of it.
header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
The `finally` clause works for *any* exit from `try..catch`. That includes an explicit `return`.

In the example below, there's a `return` in `try`. In this case, `finally` is executed just before the control returns to the outer code.

```js run
function func() {

try {
*!*
return 1;
*/!*

} catch (e) {
/* ... */
} finally {
*!*
alert( 'finally' );
*/!*
}
}

alert( func() ); // first works alert from finally, and then this one
```
header
1
2
3
4
5
6
7
8
9
10
11
12
13
14

The `try..finally` construct, without `catch` clause, is also useful. We apply it when we don't want to handle errors here (let them fall through), but want to be sure that processes that we started are finalized.

```js
function func() {
// start doing something that needs completion (like measurements)
try {
// ...
} finally {
// complete that thing even if all dies
}
}
```
In the code above, an error inside `try` always falls out, because there's no `catch`. But `finally` works before the execution flow leaves the function.

Global catch

header
1
The information from this section is not a part of the core JavaScript.

Let’s imagine we’ve got a fatal error outside of try..catch, and the script died. Like a programming error or some other terrible thing.

Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally they don’t see error messages), etc.

There is none in the specification, but environments usually provide it, because it’s really useful. For instance, Node.js has process.on("uncaughtException") for that. And in the browser we can assign a function to the special window.onerror property, that will run in case of an uncaught error.

The syntax:

1
2
3
window.onerror = function(message, url, line, col, error) {
// ...
};
message
Error message.
url
URL of the script where error happened.
line, col
Line and column numbers where error happened.
error
Error object.

For instance:

run untrusted refresh height
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
*!*
window.onerror = function(message, url, line, col, error) {
alert(`${message}\n At ${line}:${col} of ${url}`);
};
*/!*

function readData() {
badFunc(); // Whoops, something went wrong!
}

readData();
</script>

The role of the global handler window.onerror is usually not to recover the script execution – that’s probably impossible in case of programming errors, but to send the error message to developers.

There are also web-services that provide error-logging for such cases, like https://errorception.com or http://www.muscula.com.

They work like this:

  1. We register at the service and get a piece of JS (or a script URL) from them to insert on pages.
  2. That JS script sets a custom window.onerror function.
  3. When an error occurs, it sends a network request about it to the service.
  4. We can log in to the service web interface and see errors.

Summary

The try..catch construct allows to handle runtime errors. It literally allows to “try” running the code and “catch” errors that may occur in it.

The syntax is:

1
2
3
4
5
6
7
8
try {
// run this code
} catch(err) {
// if an error happened, then jump here
// err is the error object
} finally {
// do in any case after try/catch
}

There may be no catch section or no finally, so shorter constructs try..catch and try..finally are also valid.

Error objects have following properties:

  • message – the human-readable error message.
  • name – the string with error name (error constructor name).
  • stack (non-standard, but well-supported) – the stack at the moment of error creation.

If an error object is not needed, we can omit it by using catch { instead of catch(err) {.

We can also generate our own errors using the throw operator. Technically, the argument of throw can be anything, but usually it’s an error object inheriting from the built-in Error class. More on extending errors in the next chapter.

Rethrowing is a very important pattern of error handling: a catch block usually expects and knows how to handle the particular error type, so it should rethrow errors it doesn’t know.

Even if we don’t have try..catch, most environments allow us to setup a “global” error handler to catch errors that “fall out”. In-browser, that’s window.onerror.

Custom errors, extending Error

When we develop something, we often need our own error classes to reflect specific things that may go wrong in our tasks. For errors in network operations we may need HttpError, for database operations DbError, for searching operations NotFoundError and so on.

Our errors should support basic error properties like message, name and, preferably, stack. But they also may have other properties of their own, e.g. HttpError objects may have a statusCode property with a value like 404 or 403 or 500.

JavaScript allows to use throw with any argument, so technically our custom error classes don’t need to inherit from Error. But if we inherit, then it becomes possible to use obj instanceof Error to identify error objects. So it’s better to inherit from it.

As the application grows, our own errors naturally form a hierarchy. For instance, HttpTimeoutError may inherit from HttpError, and so on.

Extending Error

As an example, let’s consider a function readUser(json) that should read JSON with user data.

Here’s an example of how a valid json may look:

1
let json = `{ "name": "John", "age": 30 }`;

Internally, we’ll use JSON.parse. If it receives malformed json, then it throws SyntaxError. But even if json is syntactically correct, that doesn’t mean that it’s a valid user, right? It may miss the necessary data. For instance, it may not have name and age properties that are essential for our users.

Our function readUser(json) will not only read JSON, but check (“validate”) the data. If there are no required fields, or the format is wrong, then that’s an error. And that’s not a SyntaxError, because the data is syntactically correct, but another kind of error. We’ll call it ValidationError and create a class for it. An error of that kind should also carry the information about the offending field.

Our ValidationError class should inherit from the built-in Error class.

That class is built-in, but here’s its approximate code so we can understand what we’re extending:

1
2
3
4
5
6
7
8
// The "pseudocode" for the built-in Error class defined by JavaScript itself
class Error {
constructor(message) {
this.message = message;
this.name = "Error"; // (different names for different built-in error classes)
this.stack = <call stack>; // non-standard, but most environments support it
}
}

Now let’s inherit ValidationError from it and try it in action:

run untrusted
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*!*
class ValidationError extends Error {
*/!*
constructor(message) {
super(message); // (1)
this.name = "ValidationError"; // (2)
}
}

function test() {
throw new ValidationError("Whoops!");
}

try {
test();
} catch(err) {
alert(err.message); // Whoops!
alert(err.name); // ValidationError
alert(err.stack); // a list of nested calls with line numbers for each
}

Please note: in the line (1) we call the parent constructor. JavaScript requires us to call super in the child constructor, so that’s obligatory. The parent constructor sets the message property.

The parent constructor also sets the name property to "Error", so in the line (2) we reset it to the right value.

Let’s try to use it in readUser(json):

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}

// Usage
function readUser(json) {
let user = JSON.parse(json);

if (!user.age) {
throw new ValidationError("No field: age");
}
if (!user.name) {
throw new ValidationError("No field: name");
}

return user;
}

// Working example with try..catch

try {
let user = readUser('{ "age": 25 }');
} catch (err) {
if (err instanceof ValidationError) {
*!*
alert("Invalid data: " + err.message); // Invalid data: No field: name
*/!*
} else if (err instanceof SyntaxError) { // (*)
alert("JSON Syntax Error: " + err.message);
} else {
throw err; // unknown error, rethrow it (**)
}
}

The try..catch block in the code above handles both our ValidationError and the built-in SyntaxError from JSON.parse.

Please take a look at how we use instanceof to check for the specific error type in the line (*).

We could also look at err.name, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// ...
// instead of (err instanceof SyntaxError)
} else if (err.name == "SyntaxError") { // (*)
// ...
```

The `instanceof` version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like `PropertyRequiredError`. And `instanceof` check will continue to work for new inheriting classes. So that's future-proof.

Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or other unknown ones) should fall through.

## Further inheritance

The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age`). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.

```js run
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}

*!*
class PropertyRequiredError extends ValidationError {
constructor(property) {
super("No property: " + property);
this.name = "PropertyRequiredError";
this.property = property;
}
}
*/!*

// Usage
function readUser(json) {
let user = JSON.parse(json);

if (!user.age) {
throw new PropertyRequiredError("age");
}
if (!user.name) {
throw new PropertyRequiredError("name");
}

return user;
}

// Working example with try..catch

try {
let user = readUser('{ "age": 25 }');
} catch (err) {
if (err instanceof ValidationError) {
*!*
alert("Invalid data: " + err.message); // Invalid data: No property: name
alert(err.name); // PropertyRequiredError
alert(err.property); // name
*/!*
} else if (err instanceof SyntaxError) {
alert("JSON Syntax Error: " + err.message);
} else {
throw err; // unknown error, rethrow it
}
}

The new class PropertyRequiredError is easy to use: we only need to pass the property name: new PropertyRequiredError(property). The human-readable message is generated by the constructor.

Please note that this.name in PropertyRequiredError constructor is again assigned manually. That may become a bit tedious – to assign this.name = <class name> in every custom error class. We can avoid it by making our own “basic error” class that assigns this.name = this.constructor.name. And then inherit all our custom errors from it.

Let’s call it MyError.

Here’s the code with MyError and other custom error classes, simplified:

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyError extends Error {
constructor(message) {
super(message);
*!*
this.name = this.constructor.name;
*/!*
}
}

class ValidationError extends MyError { }

class PropertyRequiredError extends ValidationError {
constructor(property) {
super("No property: " + property);
this.property = property;
}
}

// name is correct
alert( new PropertyRequiredError("field").name ); // PropertyRequiredError

Now custom errors are much shorter, especially ValidationError, as we got rid of the "this.name = ..." line in the constructor.

Wrapping exceptions

The purpose of the function readUser in the code above is “to read the user data”. There may occur different kinds of errors in the process. Right now we have SyntaxError and ValidationError, but in the future readUser function may grow and probably generate other kinds of errors.

The code which calls readUser should handle these errors. Right now it uses multiple ifs in the catch block, that check the class and handle known errors and rethrow the unknown ones. But if the readUser function generates several kinds of errors, then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls readUser?

Often the answer is “No”: the outer code wants to be “one level above all that”, it just wants to have some kind of “data reading error” – why exactly it happened is often irrelevant (the error message describes it). Or, even better, it could have a way to get the error details, but only if we need to.

So let’s make a new class ReadError to represent such errors. If an error occurs inside readUser, we’ll catch it there and generate ReadError. We’ll also keep the reference to the original error in its cause property. Then the outer code will only have to check for ReadError.

Here’s the code that defines ReadError and demonstrates its use in readUser and try..catch:

run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class ReadError extends Error {
constructor(message, cause) {
super(message);
this.cause = cause;
this.name = 'ReadError';
}
}

class ValidationError extends Error { /*...*/ }
class PropertyRequiredError extends ValidationError { /* ... */ }

function validateUser(user) {
if (!user.age) {
throw new PropertyRequiredError("age");
}

if (!user.name) {
throw new PropertyRequiredError("name");
}
}

function readUser(json) {
let user;

try {
user = JSON.parse(json);
} catch (err) {
*!*
if (err instanceof SyntaxError) {
throw new ReadError("Syntax Error", err);
} else {
throw err;
}
*/!*
}

try {
validateUser(user);
} catch (err) {
*!*
if (err instanceof ValidationError) {
throw new ReadError("Validation Error", err);
} else {
throw err;
}
*/!*
}

}

try {
readUser('{bad json}');
} catch (e) {
if (e instanceof ReadError) {
*!*
alert(e);
// Original error: SyntaxError: Unexpected token b in JSON at position 1
alert("Original error: " + e.cause);
*/!*
} else {
throw e;
}
}

In the code above, readUser works exactly as described – catches syntax and validation errors and throws ReadError errors instead (unknown errors are rethrown as usual).

So the outer code checks instanceof ReadError and that’s it. No need to list all possible error types.

The approach is called “wrapping exceptions”, because we take “low level exceptions” and “wrap” them into ReadError that is more abstract and more convenient to use for the calling code. It is widely used in object-oriented programming.

Summary

  • We can inherit from Error and other built-in error classes normally. We just need to take care of the name property and don’t forget to call super.
  • We can use instanceof to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from a 3rd-party library and there’s no easy way to get its class. Then name property can be used for such checks.
  • Wrapping exceptions is a widespread technique: a function handles low-level exceptions and creates higher-level errors instead of various low-level ones. Low-level exceptions sometimes become properties of that object like err.cause in the examples above, but that’s not strictly required.

Animation using Pure Javascript

To bounce we can use CSS property top and position:absolute for the ball inside the field with position:relative.

The bottom coordinate of the field is field.clientHeight. The CSS top property refers to the upper edge of the ball. So it should go from 0 till field.clientHeight - ball.clientHeight, that’s the final lowest position of the upper edge of the ball.

To to get the “bouncing” effect we can use the timing function bounce in easeOut mode.

Here’s the final code for the animation:

1
2
3
4
5
6
7
8
9
let to = field.clientHeight - ball.clientHeight;

animate({
duration: 2000,
timing: makeEaseOut(bounce),
draw(progress) {
ball.style.top = to * progress + 'px'
}
});

In the task info:task/animate-ball we had only one property to animate. Now we need one more: elem.style.left.

The horizontal coordinate changes by another law: it does not “bounce”, but gradually increases shifting the ball to the right.

We can write one more animate for it.

As the time function we could use linear, but something like makeEaseOut(quad) looks much better.

The code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let height = field.clientHeight - ball.clientHeight;
let width = 100;

// animate top (bouncing)
animate({
duration: 2000,
timing: makeEaseOut(bounce),
draw: function(progress) {
ball.style.top = height * progress + 'px'
}
});

// animate left (moving to the right)
animate({
duration: 2000,
timing: makeEaseOut(quad),
draw: function(progress) {
ball.style.left = width * progress + "px"
}
});

Javascript Regular Expression - Character Classes

Character classes

Consider a practical task – we have a phone number like "+7(903)-123-45-67", and we need to turn it into pure numbers: 79035419441.

To do so, we can find and remove anything that’s not a number. Character classes can help with that.

A character class is a special notation that matches any symbol from a certain set.

For the start, let’s explore the “digit” class. It’s written as pattern:\d and corresponds to “any single digit”.

For instance, the let’s find the first digit in the phone number:

run
1
2
3
4
5
let str = "+7(903)-123-45-67";

let regexp = /\d/;

alert( str.match(regexp) ); // 7

Without the flag pattern:g, the regular expression only looks for the first match, that is the first digit pattern:\d.

Let’s add the pattern:g flag to find all digits:

run
1
2
3
4
5
6
7
8
let str = "+7(903)-123-45-67";

let regexp = /\d/g;

alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7

// let's make the digits-only phone number of them:
alert( str.match(regexp).join('') ); // 79035419441

That was a character class for digits. There are other character classes as well.

Most used are:

pattern:\d (“d” is from “digit”)
A digit: a character from 0 to 9.
pattern:\s (“s” is from “space”)
A space symbol: includes spaces, tabs \t, newlines \n and few other rare characters, such as \v, \f and \r.
pattern:\w (“w” is from “word”)
A “wordly” character: either a letter of Latin alphabet or a digit or an underscore _. Non-Latin letters (like cyrillic or hindi) do not belong to pattern:\w.

For instance, pattern:\d\s\w means a “digit” followed by a “space character” followed by a “wordly character”, such as match:1 a.

A regexp may contain both regular symbols and character classes.

For instance, pattern:CSS\d matches a string match:CSS with a digit after it:

run
1
2
3
4
let str = "Is there CSS4?";
let regexp = /CSS\d/

alert( str.match(regexp) ); // CSS4

Also we can use many character classes:

run
1
alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5'

The match (each regexp character class has the corresponding result character):

Inverse classes

For every character class there exists an “inverse class”, denoted with the same letter, but uppercased.

The “inverse” means that it matches all other characters, for instance:

pattern:\D
Non-digit: any character except pattern:\d, for instance a letter.
pattern:\S
Non-space: any character except pattern:\s, for instance a letter.
pattern:\W
Non-wordly character: anything but pattern:\w, e.g a non-latin letter or a space.

In the beginning of the chapter we saw how to make a number-only phone number from a string like subject:+7(903)-123-45-67: find all digits and join them.

run
1
2
3
let str = "+7(903)-123-45-67";

alert( str.match(/\d/g).join('') ); // 79031234567

An alternative, shorter way is to find non-digits pattern:\D and remove them from the string:

run
1
2
3
let str = "+7(903)-123-45-67";

alert( str.replace(/\D/g, "") ); // 79031234567

A dot is “any character”

A dot pattern:. is a special character class that matches “any character except a newline”.

For instance:

run
1
alert( "Z".match(/./) ); // Z

Or in the middle of a regexp:

run
1
2
3
4
5
let regexp = /CS.4/;

alert( "CSS4".match(regexp) ); // CSS4
alert( "CS-4".match(regexp) ); // CS-4
alert( "CS 4".match(regexp) ); // CS 4 (space is also a character)

Please note that a dot means “any character”, but not the “absense of a character”. There must be a character to match it:

run
1
alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot

Dot as literally any character with “s” flag

By default, a dot doesn’t match the newline character \n.

For instance, the regexp pattern:A.B matches match:A, and then match:B with any character between them, except a newline \n:

run
1
alert( "A\nB".match(/A.B/) ); // null (no match)

There are many situations when we’d like a dot to mean literally “any character”, newline included.

That’s what flag pattern:s does. If a regexp has it, then a dot pattern:. matches literally any character:

run
1
alert( "A\nB".match(/A.B/s) ); // A\nB (match!)
header
1
2
3
4
5
6
7
8
9
10
11
Check <https://caniuse.com/#search=dotall> for the most recent state of support. At the time of writing it doesn't include Firefox, IE, Edge.

Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character".

```js run
alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)
```

The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter.

This trick works everywhere. Also we can use it if we don't want to set `pattern:s` flag, in cases when we want a regular "no-newline" dot too in the pattern.
header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical.

But if a regexp doesn't take spaces into account, it may fail to work.

Let's try to find digits separated by a hyphen:

```js run
alert( "1 - 5".match(/\d-\d/) ); // null, no match!
```

Let's fix it adding spaces into the regexp `pattern:\d - \d`:

```js run
alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works
// or we can use \s class:
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works
```

**A space is a character. Equal in importance with any other character.**

We can't add or remove spaces from a regular expression and expect to work the same.

In other words, in a regular expression all characters matter, spaces too.

Summary

There exist following character classes:

  • pattern:\d – digits.
  • pattern:\D – non-digits.
  • pattern:\s – space symbols, tabs, newlines.
  • pattern:\S – all but pattern:\s.
  • pattern:\w – Latin letters, digits, underscore '_'.
  • pattern:\W – all but pattern:\w.
  • pattern:. – any character if with the regexp 's' flag, otherwise any except a newline \n.

…But that’s not all!

Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it’s a letter) it is it a punctuation sign, etc.

We can search by these properties as well. That requires flag pattern:u, covered in the next article.

Regular Expression in Javascript

Patterns and flags

Regular expressions are patterns that provide a powerful way to search and replace in text.

In JavaScript, they are available via the RegExp object, as well as being integrated in methods of strings.

Regular Expressions

A regular expression (also “regexp”, or just “reg”) consists of a pattern and optional flags.

There are two syntaxes that can be used to create a regular expression object.

The “long” syntax:

1
regexp = new RegExp("pattern", "flags");

And the “short” one, using slashes "/":

1
2
regexp = /pattern/; // no flags
regexp = /pattern/gmi; // with flags g,m and i (to be covered soon)

Slashes pattern:/.../ tell JavaScript that we are creating a regular expression. They play the same role as quotes for strings.

In both cases regexp becomes an instance of the built-in RegExp class.

The main difference between these two syntaxes is that pattern using slashes /.../ does not allow for expressions to be inserted (like string template literals with ${...}). They are fully static.

Slashes are used when we know the regular expression at the code writing time – and that’s the most common situation. While new RegExp, is more often used when we need to create a regexp “on the fly” from a dynamically generated string. For instance:

1
2
3
let tag = prompt("What tag do you want to find?", "h2");

let regexp = new RegExp(`<${tag}>`); // same as /<h2>/ if answered "h2" in the prompt above

Flags

Regular expressions may have flags that affect the search.

There are only 6 of them in JavaScript:

pattern:i
With this flag the search is case-insensitive: no difference between A and a (see the example below).
pattern:g
With this flag the search looks for all matches, without it – only the first match is returned.
pattern:m
Multiline mode (covered in the chapter info:regexp-multiline-mode).
pattern:s
Enables “dotall” mode, that allows a dot pattern:. to match newline character \n (covered in the chapter info:regexp-character-classes).
pattern:u
Enables full unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter info:regexp-unicode.
pattern:y
“Sticky” mode: searching at the exact position in the text (covered in the chapter info:regexp-sticky)
header
1
2
3
4
5
From here on the color scheme is:

- regexp -- `pattern:red`
- string (where we search) -- `subject:blue`
- result -- `match:green`

Searching: str.match

As mentioned previously, regular expressions are integrated with string methods.

The method str.match(regexp) finds all matches of regexp in the string str.

It has 3 working modes:

  1. If the regular expression has flag pattern:g, it returns an array of all matches:

    run
    1
    2
    3
    let str = "We will, we will rock you";

    alert( str.match(/we/gi) ); // We,we (an array of 2 substrings that match)

    Please note that both match:We and match:we are found, because flag pattern:i makes the regular expression case-insensitive.

  2. If there’s no such flag it returns only the first match in the form of an array, with the full match at index 0 and some additional details in properties:

    run
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let str = "We will, we will rock you";

    let result = str.match(/we/i); // without flag g

    alert( result[0] ); // We (1st match)
    alert( result.length ); // 1

    // Details:
    alert( result.index ); // 0 (position of the match)
    alert( result.input ); // We will, we will rock you (source string)

    The array may have other indexes, besides 0 if a part of the regular expression is enclosed in parentheses. We’ll cover that in the chapter info:regexp-groups.

  3. And, finally, if there are no matches, null is returned (doesn’t matter if there’s flag pattern:g or not).

    This a very important nuance. If there are no matches, we don’t receive an empty array, but instead receive null. Forgetting about that may lead to errors, e.g.:

    run
    1
    2
    3
    4
    5
    let matches = "JavaScript".match(/HTML/); // = null

    if (!matches.length) { // Error: Cannot read property 'length' of null
    alert("Error in the line above");
    }

    If we’d like the result to always be an array, we can write it this way:

    run
    1
    2
    3
    4
    5
    let matches = "JavaScript".match(/HTML/)*!* || []*/!*;

    if (!matches.length) {
    alert("No matches"); // now it works
    }

Replacing: str.replace

The method str.replace(regexp, replacement) replaces matches found using regexp in string str with replacement (all matches if there’s flag pattern:g, otherwise, only the first one).

For instance:

run
1
2
3
4
5
// no flag g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will

// with flag g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will

The second argument is the replacement string. We can use special character combinations in it to insert fragments of the match:

Symbols Action in the replacement string
$& inserts the whole match
$` inserts a part of the string before the match
$' inserts a part of the string after the match
$n if n is a 1-2 digit number, then it inserts the contents of n-th parentheses, more about it in the chapter info:regexp-groups
$<name> inserts the contents of the parentheses with the given name, more about it in the chapter info:regexp-groups
$$ inserts character $

An example with pattern:$&:

run
1
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript

Testing: regexp.test

The method regexp.test(str) looks for at least one match, if found, returns true, otherwise false.

run
1
2
3
4
let str = "I love JavaScript";
let regexp = /LOVE/i;

alert( regexp.test(str) ); // true

Later in this chapter we’ll study more regular expressions, walk through more examples, and also meet other methods.

Full information about the methods is given in the article info:regexp-methods.

Summary

  • A regular expression consists of a pattern and optional flags: pattern:g, pattern:i, pattern:m, pattern:u, pattern:s, pattern:y.
  • Without flags and special symbols (that we’ll study later), the search by a regexp is the same as a substring search.
  • The method str.match(regexp) looks for matches: all of them if there’s pattern:g flag, otherwise, only the first one.
  • The method str.replace(regexp, replacement) replaces matches found using regexp with replacement: all of them if there’s pattern:g flag, otherwise only the first one.
  • The method regexp.test(str) returns true if there’s at least one match, otherwise, it returns false.