Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

JavaScript is used

If you don’t know any JavaScript, this is a quick 5-minute course explaining most things you will need to understand.

Full JavaScript Docs

If you need a more in-depth explanation, you can look up anything on developer.mozilla.org, everything except for the DOM.

Types in JavaScript do not exist

In Groovy and Java, you can explicitly declare the type of a variable or the return type of a function. This is called static typing (Groovy has a mix of static and dynamic typing).

JavaScript, on the other hand, uses dynamic typing. This means:

  1. You don't declare types for variables or functions.

  2. Types are automatically assigned at runtime based on the value assigned to the variable or returned by the function.

  3. A variable's type can change during program execution if you assign it a different type of value (for example: variable from string can become a number when using if with two equal signs ==, three equal signs also evaluate type ===).

let number = 5;        // Automatically typed as a number
let text = "Hello";    // Automatically typed as a string

function add(a, b) {
    return a + b;      // Return type depends on the input
}

console.log(typeof number);  // Outputs: "number"
console.log(typeof text);    // Outputs: "string"
console.log(typeof add);     // Outputs: "function"

console.log(typeof number === typeof text)  // Outputs: false

Semicolons are optional

Semicolons in JavaScript are optional, same as in Java and Groovy. Read more in automatic semicolon insertions.

Logging

// Display's word hello in browser console.
console.log('hello');

// Show in the console object data from crm
const payload = await crmManager.getPayload();
console.log(`This is data from the payload ${payload}`);

Variables

To define a variable, use the let or const keyword. Don’t use var as it is a global variable and can conflict with interceptor, app and CRM.

let someString = 'some-string'

let someNumber = 69

let someBool = true

// In groovy it same
const array = ['string', 69, true]

// In groovy it would be called map
const object = {
  key: 'value',
  'key-word': 'value',
}

String formatting

use backticks and ${}

const string = 'pricefx'
const formatted = `Hi ${string}`
console.log(formatted) // Hi pricefx

Flow control

// If-else statement
let i = 0;
if (i < 0) {
  console.log("it's negative");
} else if (i > 0) {
  console.log("it's more than 0");
} else {
  console.log("it's 0");
}

// Logical operators (&& and ||)
let x = 5;
let y = 10;

// AND (&&) operator
if (x > 0 && y > 0) {
  console.log("Both x and y are positive");
}

// OR (||) operator
if (x < 0 || y > 5) {
  console.log("Either x is negative or y is greater than 5 (or both)");
}

// Ternary operator
let result = i < 0 ? "it's negative" : "it's 0 or more than 0";
console.log(result);

// While loop
let j = 0;
while (j < 5) {
  console.log(j);
  j++;
}

// For loop
for (let k = 0; k < 5; k++) {
  console.log(k);
}

// For...of loop
const array = [0, 1, 2, 3, 4];
for (const item of array) {
  console.log(item);
}

// Do...while loop
let m = 0;
do {
  console.log(m);
  m++;
} while (m < 5);

// For...in loop (for object properties)
const person = { name: "John", age: 30, job: "Developer" };
for (const key in person) {
  console.log(`${key}: ${person[key]}`);
}

// Switch statement
let day = "Monday";
switch (day) {
  case "Monday":
    console.log("Start of the work week");
    break;
  case "Friday":
    console.log("TGIF!");
    break;
  default:
    console.log("It's a regular day");
}

Functions

There are multiple ways to define functions, with the function keyword or with arrow functions, also known as lambda functions in other languages.

  1. Arrow function (lambda function):

const fn = (param1, param2) => {
  console.log(param1, param2);
  return `${param1} ${param2}`;
}
const greeting = fn('Hola', 'pfx'); 
// greeting is now equivalent to 'Hola pfx', and you have displayed it in console.
  1. Regular function:

const fn = function fn(param1, param2) {
  console.log(param1, param2);
  return `${param1} ${param2}`;
}
const greeting = fn('Hola', 'pfx'); 
// greeting is now equivalent to 'Hola pfx', and you have displayed it in console.

Normally, arrow function should be preferred when writing interceptors, as arrow function follow the functional code paradigm and regular function are more for OOP.

Differences between arrow and regular function

  1. this binding:

    • Regular: Has its own this context

    • Arrow: Inherits this from the enclosing scope

      const obj = {
          name: 'pfx',
          sayHiRegular: function() {
              console.log('Hi, ' + this.name);
          },
          sayHiArrow: () => {
              console.log('Hi, ' + this.name);
          }
      };
      
      obj.sayHiRegular(); // Outputs: Hi, pfx
      obj.sayHiArrow();   // Outputs: Hi, undefined
  2. Arguments object:

    • Regular: Has arguments object

    • Arrow: Doesn't have arguments object

      function regularFunc() {
          console.log(arguments);
      }
      
      const arrowFunc = () => {
          console.log(arguments);
      };
      
      regularFunc(1, 2, 3); // Outputs: [1, 2, 3]
      arrowFunc(1, 2, 3);   // Throws ReferenceError: arguments is not defined
  3. Use as methods:

    • Regular: Can be used as object methods

    • Arrow: Not suitable for object methods (due to 'this' binding)

      function regularFunc() {
          console.log(arguments);
      }
      
      const arrowFunc = () => {
          console.log(arguments);
      };
      
      regularFunc(1, 2, 3); // Outputs: [1, 2, 3]
      arrowFunc(1, 2, 3);   // Throws ReferenceError: arguments is not defined
  4. Function hoisting:

    • Regular: Can be hoisted

    • Arrow: Cannot be hoisted

      console.log(regularHoisted()); // Outputs: "I'm hoisted!"
      function regularHoisted() {
          return "I'm hoisted!";
      }
      
      // Uncommenting the next line would throw a ReferenceError
      console.log(arrowHoisted());
      const arrowHoisted = () => "I'm not hoisted!";
  5. Constructors:

    • Regular: Can be used as constructors

    • Arrow: Cannot be used as constructors

      function RegularConstructor() {
          this.value = 42;
      }
      const regularInstance = new RegularConstructor();
      console.log(regularInstance.value); // Outputs: 42
      
      const ArrowConstructor = () => {
          this.value = 42;
      };
      // Uncommenting the next line would throw a TypeError
      // const arrowInstance = new ArrowConstructor();

Additionally, JavaScript supports default parameter values, which can be used to provide a default value for a parameter if no value is provided when the function is called. Here's an example:

const fn = (param1, param2 = 'hello') => {
  console.log(param1, param2);
}

fn(); // Outputs: undefined, hello

Destructuring

Arrays

// Initialize an array with five elements
const array = [1, 2, 3, 4, 5];

// Use array destructuring to assign the first two elements to variables,
// and the rest of the elements to a new array called 'rest'
const [elem1, elem2, ...rest] = array;

// Log the values of the variables to the console
console.log(elem1, elem2, rest); // Outputs: 1, 2, [3, 4, 5]

Objects

// Initialize an object with four properties
const object = {one: 1, two: 2, three: 3, four: 4};

// Use object destructuring to assign the values of the 'one' and 'two' properties to variables,
// and the rest of the properties to a new object called 'rest'
const {one, two, ...rest} = object;

// Log the values of the variables to the console
console.log(one, two, rest); // Outputs: 1, 2, {three: 3, four: 4}

Promises/Async (await, then)

Groovy Async is a niche topic and may be a completely new concept to you. But it's everywhere in JavaScript.

Async and Sync

  • Synchronous: Operations are executed in sequence. Each operation must finish before the next one starts.

  • Asynchronous: Operations can be executed in parallel. The program doesn't wait for an operation to finish before moving to the next one.

Why to use :

  • Using Promises: The program continues executing while waiting for the async operation, hence "End" is logged before the result.

  • Using async/await: It allows writing asynchronous code that looks synchronous, making it easier to read and understand.

Asynchronous operations are crucial for handling time-consuming tasks (like API calls or file operations) without blocking the main thread of execution.

In Interceptors, JavaScript await and then are used to handle data fetch from CRM and other sources.

Await

await is a keyword that can be used inside an async function to pause the execution of the function until a Promise is resolved or rejected. This allows us to write asynchronous code in a more synchronous-looking way, making it easier to understand and maintain.

Here's an example of using await to get payload from CRM:

const fetchData = async (crmManager) => {
  const response = await crmManager.getPayload();
  console.log(response);
}

fetchData(); // { name: 'Zalgiris', id: '19860815', ... }

Without await, you would get unfulfilled promise which doesn't have anything to return or show:

const fetchData = (crmManager) => {
  const response = crmManager.getPayload();
  console.log(response);
}

fetchData(); // Promise<Pending>
// This happened because console.log accessed response
// while it is still being executed

Then

then is a method used to handle the resolution or rejection of a Promise by providing callback functions to be executed when the Promise is resolved or rejected, allowing for the chaining of asynchronous operations.

This is not as complicated as it may seem.

Here's an example of using then to handle getPayload:

crmManager.getPayload()
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.log(error);
  });

try...catch...finally

Between Groovy and JavaScript try...catch...finally works same. Here is example for JS

function divide(a, b) {
    try {
        console.log("Attempting division...");
        if (b === 0) {
            throw new Error("Cannot divide by zero");
        }
        let result = a / b;
        console.log(`Result: ${result}`);
        return result;
    } catch (error) {
        console.error(`An error occurred: ${error.message}`);
        return null;
    } finally {
        console.log("Division operation completed");
    }
}

console.log(divide(10, 2));  // Normal case
console.log(divide(10, 0));  // Error case

// Output:
// Attempting division...
// Result: 5
// Division operation completed
// 5
// Attempting division...
// An error occurred: Cannot divide by zero
// Division operation completed
// null
  • No labels