Loading...

Follow Codedam Blog on Feedspot

Continue with Google
Continue with Facebook
or

Valid

The post 8 NEW FEATURES in JavaScript ES2019 appeared first on Codedam.

I personally love how JavaScript keeps improving and adding more features. TC39 has finished and approved this 8 features for ES2019 which has 4 stages and those stages are. Stage 0: Strawman Stage 1: Proposals Stage 2: Drafts Stage 3: Read more…

The post 8 NEW FEATURES in JavaScript ES2019 appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

The post JavaScript Random Facts – Null is an object appeared first on Codedam.

This is my third post for the series “Just so you know” where we are going to unlock deeper knowledge about JavaScript codes. For those who are new here in this blog, this series talks about things that some of you Read more…

The post JavaScript Random Facts – Null is an object appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

The post Just so you know: Uncommonly used Array Methods appeared first on Codedam.

Welcome to the second episode of the “Just so you know” series where we talk about Array Methods in JavaScript. For those who are new here in this blog, this series talks about things that some of you might not Read more…

The post Just so you know: Uncommonly used Array Methods appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

This is my first blog for the series called “Just so you know” where I will talk about things that you might already know or not. So for now we going to talk about Functional Programming.

What is Functional Programming?

a programming paradigm just like OOP where you have objects with methods in them, Structured Programming, Procedural and more however Functional Programming is where functions is the main character. Basically functional programming provides pure function and avoids things like mutable data or side effects. so most likely the data enters as an input and the function will provide an output without affecting any variables.

Why Use Functional Programming?
  1. Easier to understand.
  2. Easier to debug.
  3. Reduce duplicate codes.
  4. Easier to test using testing scripts.
  5. Easier to predict its output.
  6. Avoid unwanted variable value changes.

So know we know the basic meaning of Functional Programming. Let’s see an example implementation.

Not Functional

const name = 'Rienz Otiong'; 
const greet = `Hi! ${name}, Welcome to Codedam`;

console.log(greet); // returns Hi! Rienz Otiong, Welcome to Codedam

Functional

const name = 'Rienz Otiong'; 
const greet = str => `Hi! ${str}, Welcome to Codedam`;

console.log(greet(name)); // returns Hi! Rienz Otiong, Welcome to Codedam
Pure Function

Functional Programming takes an input and use only that given input to provide an output which produces no side effects.

Side Effects  is an effect where it uses an external variable that is not within function or calling an external process like triggering a file edit or printing on the display. Pure Functions will make you avoid any unexpected output or unwanted process.

Not Functional (Impure Function)

let name = 'Rienz Otiong'; 
const greet = () => `Hi! ${name}, Welcome to Codedam`;

Functional (Pure Function)

let name = 'Rienz Otiong'; 
const greet = str => `Hi! ${str}, Welcome to Codedam`;
Higher Order Function

Higher Order Function is a function within a function or can take functions as inputs and/or output.

const addition = num1 => num2 => num1 + num2;
const addFour = addition(4);

console.log(addFour(8)); // returns 12

const fourPlusTwo = addition(4)(2);

console.log(fourPlusTwo); // returns 6

is same as

const addition = function(num1) {
    return function(num2) {
        return num1 + num2;
    }
};

const addFour = addition(4);

console.log(addFour(8)); // returns 12

const fourPlusTwo = addition(4)(2);

console.log(fourPlusTwo); // returns 6

the old way

Functional Methods (map, reduce, filter)

We might iterate an array using for loops and while loop however in a functional way to do it is use map, reduce and filter which returns a new array and doesn’t modify the original array.

So first map transform each item of the array which returns the same length of items. For example

const arr = [1, 2, 3, 4, 5];
const double = arr.map(item => item * 2);

console.log(arr); // [1, 2, 3, 4, 5]
console.log(double); // [ 2, 4, 6, 8, 10 ]

reduce on the other hand returns a data using all of the items resulting a single output value.

const arr = [1, 2, 3, 4, 5];
const sumArr = arr.reduce((acc, cur) => acc + cur);

console.log(arr); // [1, 2, 3, 4, 5]
console.log(sumArr); // 15

lastly filter where it checks every item and removes all of the items that failed on the given condition.

const arr = [1, 2, 3, 4, 5];
const arrEven = arr.filter(item => item % 2 === 0);

console.log(arr); // [1, 2, 3, 4, 5]
console.log(arrEven); // [ 2, 4 ]
Immutable Data

This is a continuation of Functional Methods on why we need to use it. Immutable Data is a data that can’t be change which enables us to debug easier since your confident that none of your methods or functions will change the value of your data. This avoids the fact that sometimes we don’t know where our data changes its value since numerous functions use and transform the value of that variable.

Mutable Data

const arr = [1, 2, 3, 4, 5];
arr[0] = 2;

console.log(arr); // [ 2, 2, 3, 4, 5 ]

Immutable Data

const arr = [1, 2, 3, 4, 5];
const newArr = arr.map(item => item === 1 ? 2 : item);

console.log(arr); // [ 1, 2, 3, 4, 5 ]
console.log(newArr); // [ 2, 2, 3, 4, 5 ]
For more “Just so you know” posts. Just click here

The post Just so you know: Functional Programming appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Spread Operator or Spread Syntax was introduced as part of the ES2015 release and have some really useful features. Basically it expands an iterable such as Array expression, Object expression or a String.

Spread Operator looks like this ... then the iterable expression for example items that would look like ...items.

Here’s an example of what it looks like.

const fruits = ['Apple', 'Mango', 'Banana'];

console.log(...fruits); // Apple Mango Banana

// is equivalent to
console.log(fruits[0], fruits[1], fruits[2]); // Apple Mango Banana

So from the word itself, it spreads an iterable expression. Another example to solidify your understanding.

const nums = [1, 2, 3];

console.log(...nums); // 1 2 3
console.log([...nums]); // [ 1, 2, 3 ]
console.log(nums); // [ 1, 2, 3 ]

From our second example you can see that we put the spread operator inside the open and close brackets to have the same result as the original array.

Now that we have the basic knowledge about it. Let’s proceed on its use cases.

Copying or Cloning

You can copy an expression and that copy is a clone so whatever you do with it, it doesn’t affect the original expression.

const arr = ['Code', 'dam'];
const arr2 = [...arr];

console.log(arr); // [ 'Code', 'dam' ]
console.log(arr2); // [ 'Code', 'dam' ]

arr2[2] = "is Awsome!";

// arr2 is changed but it doesnt affect the original which is arr
console.log(arr); // [ 'Code', 'dam' ]
console.log(arr2); // [ 'Code', 'dam', 'is Awsome!' ]


// not using spread operator but pass as reference
const arr3 = arr;

arr3[0] = "Sad";

console.log(arr3); // [ 'Sad', 'dam' ]
console.log(arr); // [ 'Sad', 'dam' ]

The old way of copying arrays are using Array.from or slice array method.

const arr = ['Code', 'dam'];
const arr2 = Array.from(arr);
const arr3 = arr.slice();

console.log(arr); // [ 'Code', 'dam' ]
console.log(arr2); // [ 'Code', 'dam' ]
console.log(arr3); // [ 'Code', 'dam' ]
Apply to a new expression

We could adopt the contents of the existing iterable expression to a new expression.

const oldArray = [1, 2, 3];
const newArray = [...oldArray, 4, 5, 6];

console.log(newArray); // [ 1, 2, 3, 4, 5, 6 ]


const oldObj = {
    name: 'Codedam'
};
const newObj = {
    ...oldObj,
    location: 'Philippines'
}

console.log(newObj); // { name: 'Codedam', location: 'Philippines' }
Concatenate Multiple Expressions

We could also concatenate multiple iterable expression in any position you want to a new expression.

// Array

const arr1 = [1, 2];
const arr2 = [4, 5];

const newArray = [2, ...arr1, 3, ...arr2, 9];

console.log(newArray); // [ 2, 1, 2, 3, 4, 5, 9 ]


// Object

const obj1 = {
    name: 'Codedam'
};
const obj2 = {
    age: 22
};
const newObj = {
    ...obj1,
    ...obj2,
    location: 'Philippines'
}

console.log(newObj); // { name: 'Codedam', age: 22, location: 'Philippines' }

The other way to do it is using Object.assign with objects and concat for arrays.

// Array

const arr1 = [1, 2];
const arr2 = [4, 5];

const newArray = arr1.concat(arr2);

console.log(newArray); // [ 1, 2, 4, 5 ]


//Object

const obj1 = {
    name: 'Codedam'
};
const obj2 = {
    age: 22
};
const newObj = Object.assign({location: 'Philippines'}, obj1, obj2)

console.log(newObj); // { location: 'Philippines', name: 'Codedam', age: 22 }
Spread as arguments

Before we use Function.prototype.apply to set array items into arguments but now we could do it with spread syntax.

function sum(x, y, z) {
    return x + y + z;
}

const arr = [1, 2, 3];


console.log(sum.apply(null, arr));  // 6

Example using spread.

function sum(x, y, z) {
    return x + y + z;
}

const arr = [1, 2, 3];


console.log(sum(...arr)); // 6
Rest Syntax

Rest Parameter looks exactly the same with Spread Syntax however rest combines the arguments into a single array. Using it means where expecting zero or more arguments to be pass in our function.

function muliplyByTen(...nums) {
    return nums.map( num => num * 10 );
}

console.log(muliplyByTen(1, 2, 3)); // [ 10, 20, 30 ]


// Combo using Spread Operator and Rest Operator

const arr = [5, 4, 3]
console.log(muliplyByTen(...arr)); // [ 50, 40, 30 ]

Also we could expect/name our first to n parameter and then assign the Rest Parameter on the end.

function muliply(miltiplier, ...nums) {
    return nums.map( num => num * miltiplier );
}

console.log(muliply(2, 2, 3, 9)); // [ 4, 6, 18 ]

Note than you could only put the Rest Syntax on the last formal parameter or else you would have an Syntax Error.

Application on in-built JavaScript functions

You can also use spread syntax on in-built JavaScript functions.

const arr = [10, 4, 5, 2, 9];

console.log(Math.max(...arr)); // 10
console.log(Math.min(...arr)); // 2


const dateFields = [2019, 1, 2];
const date = new Date(...dateFields);

console.log(date); // 2019-02-01T16:00:00.000Z
Split String

Spread Syntax can also spread strings and turn then to an array of characters which also happens when you use split function.

const str = 'Codedam';

console.log([...str]); // [ 'C', 'o', 'd', 'e', 'd', 'a', 'm' ]
console.log(str.split(''));  // [ 'C', 'o', 'd', 'e', 'd', 'a', 'm' ]
Benefits of using Spread Operator
    • Avoids mutation or the cloned expression doesn’t affects the original.
    • Better way to concat arrays (Put anywhere you like)
    • Better than using apply method (Array.prototype.push.apply(arr1, arr2) vs [...arr1, ...arr2])
    • Shorter code (some might think its not a benefit but once you get use to it, it is)
Bonus

Something important to note that the spread operator will only appear to deep copy the contents of an expression. In fact, what is going on is that any embedded object/array is simply being copied by reference.

const arr1 = [1, 2, [3, 4], {'embedded': 'obj'}];
const arr2 = [...arr1];

console.log(arr2); // [ 1, 2, [ 3, 4 ], { embedded: 'obj' } ]


// not mutating
arr2[0] = 0;

console.log(arr1); // [ 1, 2, [ 3, 4 ], { embedded: 'obj' } ]


// but can mutate array or object within the array
arr2[2][0] = 0;
arr2[3].embedded = 'changed';

console.log(arr1); // [ 1, 2, [ 0, 4 ], { embedded: 'changed' } ]
console.log(arr2); // [ 1, 2, [ 0, 4 ], { embedded: 'changed' } ]

Here’s a link reference to that problem. but It wont be a problem if your not dealing with multi dimensional array or array of objects.

You could also checkout the MDN website to check more about the spread syntax.

To learn more checkout our latest JavaScript articles. Also feel free to comment any suggestion, correction and improvements that you might want to share. that’s all, Cheers!

The post Spread Operator – Just so you know JavaScript appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

This is my third post for the series “Just so you know” where we are going to unlock deeper knowledge about JavaScript codes.

For those who are new here in this blog, this series talks about things that some of you might know or not. So without further ado. Let’s proceed to our first code.

NaN (Not A Number) is a type of number.

Crazy right? even though NaN represents a “Not-a-Number” value, its a special value in which results from a operation that has a non-numeric operands. For Example 1 * 'a'

const operation = 1 * 'a'; // 1 times a

console.log(operation); // returns NaN
console.log(typeof operation); // returns 'number'
Null is an object.

To summarize this, null is an assigned value which means nothing. On the other hand undefined is a declared variable but not defined yet. So be careful if you have an if statement that detects whether a value is an object since null is one of them.

While typeof null returns "object", it’s not actually an object, quite silly right? it’s consider as primitive. This is a bug in JavaScript that apparently can’t be fixed without breaking JavaScript.

console.log(typeof null); // object
console.log(null === undefined); // false
console.log(null == undefined); // true
Access more than expected function parameters

Basically we could use the rest parameters which represent an indefinite number of arguments as an array.

function sum(...num) {
    return Array.from(num).reduce((acc, cur) => acc + cur);
}

console.log(sum(1, 2)); // returns 3
console.log(sum(1, 2, 3, 4, 5)); // returns 15

Another example using arrow function.

const sum = (...num) => Array.from(num).reduce((acc, cur) => acc + cur);

console.log(sum(1, 2)); // returns 3 
console.log(sum(1, 2, 3, 4, 5)); // returns 15
Array reverse() method

As we all know that reverse method return the array in reverse order. However the interesting part is that it reverse also the order of the original array and it returns itself so whatever you do with the assigned variable will also happen to the original array which doesn’t happen most of Array methods like map, reduce or filter.

// Map example which doesn't mutate the original variable

const arrMap1 = [1, 2, 3];
const arrMap2 = arrMap1.map( item => item * 2 );

console.log(arrMap1); // returns [ 1, 2, 3 ]
console.log(arrMap2); // returns [ 2, 4, 6 ]

arrMap2.pop();

console.log(arrMap1); // returns [ 1, 2, 3 ]
console.log(arrMap2); // returns [ 2, 4 ]


// Reduce example which mutates the original variable

const arrReverse1 = [1, 2, 3];
const arrReverse2 = arrReverse1.reverse();

console.log(arrReverse1); // returns [ 3, 2, 1 ]
console.log(arrReverse2); // returns [ 3, 2, 1 ]

arrReverse2.pop();

console.log(arrReverse1); // returns [ 3, 2 ]
console.log(arrReverse2); // returns [ 3, 2 ]
Unary plus (+)

Unary + operator converts its operand to Number type. shorthand for Number, parseInt, parseFloat

const strNumber = '10';
const string = 'a';
const boolTrue = true;
const bootFalse = false;

console.log(+strNumber);    // 10
console.log(+string);       // NaN
console.log(+boolTrue);     // 1
console.log(+bootFalse);    // 0
console.log(+null);         // 0
console.log(+undefined);    // NaN

console.log(10 + '20');     // 1020
console.log(10 + +'20');    // 30

Conditional Chain (Shorthand Version)

You might do if statement like this.

function compareNumbers(a, b) {
    if( a == b ) {
        return 'isEqual'
    } else if( a < b ) {
        return 'isLessThan'
    } else if( a > b ) {
        return 'isGreaterThan'
    } else {
        return 'Error'
    }
}

Which is fine. However you can do it in a shorter and cleaner way using shorthand if-else statement

const compareNumbers = (a, b) =>
    a == b  ? 'isEqual'
    : a < b ? 'isLessThan'
    : a > b ? 'isGreaterThan'
    : 'Error';

console.log(compareNumbers(1, 2));      // isLessThan
console.log(compareNumbers(9, 5));      // isGreaterThan
console.log(compareNumbers(3, '3'));    // isEqual
console.log(compareNumbers(3, 'a'));    // Error
Copying Array Items

It is better to use spread operator when copying the items of an array to avoid unnecessary mutation like the example below.

const arr = [1,2,3];
const arr1 = [...arr];
const arr2 = arr;

arr1[0] = 3;

console.log(arr);   // [ 1, 2, 3 ]
console.log(arr1);  // [ 3, 2, 3 ]

arr2[0] = 5;

console.log(arr);   // [ 5, 2, 3 ]
console.log(arr2);  // [ 5, 2, 3 ]

As you can see. arr1 doesn’t affects the original array which is arr when changing the value as you are making a new copy of array. On the other hand, arr2 is a reference for arr in which changing the value either of the two will affect both of them.

Array To Object

Most likely we search an array item by its id by using find which iterates every item inside the array.

const users = [
    {
        id: 1246,
        name: "Rienz Ivan Otiong"
    },
    {
        id: 4392,
        name: "Olivia Green"
    },
    {
        id: 9321,
        name: "Larry West"
    }
]

const findMe = users.find( item => item.id === 1246 );

console.log(findMe); // { id: 1246, name: 'Rienz Ivan Otiong' }

However it will be slower when you have like a thousand items in the array. What you can do first is make the array as object and the ids of the item would be their key so that you can easily access them rather than checking each item that has that particular id. see the example below.

const arrayToObject = ( arr,  keyField ) => arr
    .reduce( (accumulator, currentValue) => {
        accumulator[currentValue[keyField]] = currentValue;
        return accumulator;
    }, {});

const users = [
    {
        id: 1246,
        name: "Rienz Ivan Otiong"
    },
    {
        id: 4392,
        name: "Olivia Green"
    },
    {
        id: 9321,
        name: "Larry West"
    }
]

const formattedUsers = arrayToObject(users, 'id');

// So rather than using 'users.find( item => item.id === 1246 )'
// you can simply call 'formattedUsers[1246]' to get the specific user

console.log(formattedUsers[1246]);  // { id: 1246, name: 'Rienz Ivan Otiong' }
for-loop vs for-in

We often use for-in to iterate object keys but what happen if we use them in arrays.

let arr = [];   // Array Length '0'
arr[2] = 1;     // Array Length '3' (0, 1, 2)


// In for-loop by using Array.length it will iterate the array one by one even they are not defined
for (let key = 0; key < arr.length; key++) {
    console.log(arr[key]);
}


// However in for-in, only the defined items will iterate
for (let key in arr) {
    console.log(arr[key]);
}
Deep Object Comparison

Comparing different declared object will return false and only it would return true if its referring to the original object.

let objectA = { name: 'Rienz' };
let objectB = { name: 'Rienz' };

let copyObjectA = objectA;


console.log(objectA === objectB);       // false
console.log(objectA === copyObjectA);   // true

To solve this you need to deep search every property on your own.

let objectA = { name: 'Rienz' };
let objectB = { name: 'Rienz' };

function deepCompare(o1, o2) {
    // first is to check if they both referred to the same object
    if (o1 === o2) return true;

    // check if both are object
    if (typeof o1 !== 'object' || typeof o2 !== 'object') return false;

    // check if they have equal sets of property
    if (Object.keys(o1).length !== Object.keys(o2).length) return false;

    const keys = Object.keys(o1);

    // check if every keys are same
    return keys.every(key => deepCompare(o1[key], o2[key]));
};

console.log(deepCompare(objectA, objectB)); // true
For more “Just so you know” posts. Just click here

The post Just so you know: Random Facts about JavaScript appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

This is my first blog for the series called “Just so you know” where I will talk about things that you might already know or not. So for now we going to talk about Functional Programming.

What is Functional Programming?

a programming paradigm just like OOP where you have objects with methods in them, Structured Programming, Procedural and more however Functional Programming is where functions is the main character. Basically functional programming provides pure function and avoids things like mutable data or side effects. so most likely the data enters as an input and the function will provide an output without affecting any variables.

Why Use Functional Programming?
  1. Easier to understand.
  2. Easier to debug.
  3. Reduce duplicate codes.
  4. Easier to test using testing scripts.
  5. Easier to predict its output.
  6. Avoid unwanted variable value changes.

So know we know the basic meaning of Functional Programming. Let’s see an example implementation.

Not Functional

const name = 'Rienz Otiong'; 
const greet = `Hi! ${name}, Welcome to Codedam`;

console.log(greet); // returns Hi! Rienz Otiong, Welcome to Codedam

Functional

const name = 'Rienz Otiong'; 
const greet = str => `Hi! ${str}, Welcome to Codedam`;

console.log(greet(name)); // returns Hi! Rienz Otiong, Welcome to Codedam
Pure Function

Functional Programming takes an input and use only that given input to provide an output which produces no side effects.

Side Effects  is an effect where it uses an external variable that is not within function or calling an external process like triggering a file edit or printing on the display. Pure Functions will make you avoid any unexpected output or unwanted process.

Not Functional (Impure Function)

let name = 'Rienz Otiong'; 
const greet = () => `Hi! ${name}, Welcome to Codedam`;

Functional (Pure Function)

let name = 'Rienz Otiong'; 
const greet = str => `Hi! ${str}, Welcome to Codedam`;
Higher Order Function

Higher Order Function is a function within a function or can take functions as inputs and/or output.

const addition = num1 => num2 => num1 + num2;
const addFour = addition(4);

console.log(addFour(8)); // returns 12

const fourPlusTwo = addition(4)(2);

console.log(fourPlusTwo); // returns 6

is same as

const addition = function(num1) {
    return function(num2) {
        return num1 + num2;
    }
};

const addFour = addition(4);

console.log(addFour(8)); // returns 12

const fourPlusTwo = addition(4)(2);

console.log(fourPlusTwo); // returns 6

the old way

Functional Methods (map, reduce, filter)

We might iterate an array using for loops and while loop however in a functional way to do it is use map, reduce and filter which returns a new array and doesn’t modify the original array.

So first map transform each item of the array which returns the same length of items. For example

const arr = [1, 2, 3, 4, 5];
const double = arr.map(item => item * 2);

console.log(arr); // [1, 2, 3, 4, 5]
console.log(double); // [ 2, 4, 6, 8, 10 ]

reduce on the other hand returns a data using all of the items resulting a single output value.

const arr = [1, 2, 3, 4, 5];
const sumArr = arr.reduce((acc, cur) => acc + cur);

console.log(arr); // [1, 2, 3, 4, 5]
console.log(sumArr); // 15

lastly filter where it checks every item and removes all of the items that failed on the given condition.

const arr = [1, 2, 3, 4, 5];
const arrEven = arr.filter(item => item % 2 === 0);

console.log(arr); // [1, 2, 3, 4, 5]
console.log(arrEven); // [ 2, 4 ]
Immutable Data

This is a continuation of Functional Methods on why we need to use it. Immutable Data is a data that can’t be change which enables us to debug easier since your confident that none of your methods or functions will change the value of your data. This avoids the fact that sometimes we don’t know where our data changes its value since numerous functions use and transform the value of that variable.

Mutable Data

const arr = [1, 2, 3, 4, 5];
arr[0] = 2;

console.log(arr); // [ 2, 2, 3, 4, 5 ]

Immutable Data

const arr = [1, 2, 3, 4, 5];
const newArr = arr.map(item => item === 1 ? 2 : item);

console.log(arr); // [ 1, 2, 3, 4, 5 ]
console.log(newArr); // [ 2, 2, 3, 4, 5 ]
For more “Just so you know” posts. Just click here

The post Just so you know: Functional Programming appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Angular State Management is important when it comes to web applications or web tools but some external libraries in Angular are very complicated and complex on how to implement it.

Now I would share something called BehaviorSubject in rxjs which can be used as a tool to manage our state.

What is Subject?

We need to know first what is Subject. Basically it is an Observable in which you can store a value and emits the value upon using the next function.

const subject = new Subject(); 

subject.next('1');

subject.subscribe(value => {
  console.log(value);
});

// doesn't log 1
subject.next('2'); // logs 2
subject.next('3'); // logs 3
What is BehaviorSubject?

BehaviorSubject is a type of the Subject but requires an initial value and emits its latest or current value upon subscription. This is important for our Angular State Management since we could get the latest value of our data and update it whenever some changes happens.

const subject = new BehaviorSubject('0'); 

subject.next('1');

subject.subscribe(value => {
  console.log(value);
}); // logs 1 since its the current value

subject.next('2'); // logs 2
subject.next('3'); // logs 3
Creating Model and Service

Before we proceed on creating our Store class. I want to share the full potential of this topic so first lets create a Model which represents our state and Service that we can use later from our store which calls an HTTP request from an API.

export interface Post {
  id: number;
  userId: number;
  title: string;
  body: string;
}

Checking on the routes that are available in jsonplaceholder. I picked the post endpoint for us to use in our project.

import { Observable } from 'rxjs';
import { Post } from './../models/posts.model';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class PostsService {

  private url: string;

  constructor(
    private http: HttpClient
  ) {
    this.url = 'https://jsonplaceholder.typicode.com/posts';
  }

  get$ = (): Observable<Post[]> => this.http.get<Post[]>(this.url);

  post$ = (post: Post): Observable<Post> => this.http.post<Post>(this.url, { post });

  patch$ = (postId: number, post: Post): Observable<Post> => this.http.patch<Post>(`${this.url}/${postId}`, { post });

  delete$ = (postId: number): Observable<Post> => this.http.delete<Post>(`${this.url}/${postId}`);

}

Nothing crazy here just some HTTP functions in our service that we will be using in our store later.

Creating Store

Now that we know how BehaviorSubject works. Lets proceed on creating our Store class.

import { BehaviorSubject, Observable } from 'rxjs';

export abstract class Store<T> {

  private state$: BehaviorSubject<T> = new BehaviorSubject(undefined);

  getAll = (): T => this.state$.getValue();

  getAll$ = (): Observable<T> => this.state$.asObservable();

  store = (nextState: T) => (this.state$.next(nextState));

}

Let me explain one by one on what did we do here.

  • First we declare our state$ as BehaviorSubject and assign with an initial value of undefined just to visualize that no value has been stored yet.
  • Next is the getAll function which returns the current value of the store and getAll$ that returns an Observable on which we can subscribe so that our data will be updated when some changes happens in our state.
  • Lastly is the store function where we update the data on our state.
Extending Store

Here’s the fun part where we’re going to inject the Service and extend the Store. So now we’re going to extend our Store class to our PostsStore.

import { Injectable } from '@angular/core';
import { tap } from 'rxjs/operators';
import { PostsService } from '../services/posts.service';
import { Store } from './store';
import { Post } from '../models/posts.model';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PostsStore extends Store<Post[]> {

  constructor(private postsService: PostsService) {
    super();
  }

  init = (): void => {
    if (this.getAll()) { return; }

    this.postsService.get$().pipe(
      tap(this.store)
    ).subscribe();
  }

}

Then provide an initialization init function to get the data from the service and then use the store function to save the response data.

Import in Module

Don’t forget to put the store and service inside the providers of the module. also add the HttpClientModule into imports since we use HttpClient in Service.

import { PostsStore } from './stores/posts.store';
import { PostsService } from './services/posts.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [PostsService, PostsStore],
  bootstrap: [AppComponent]
})
export class AppModule { }
Display in Component

You can run the init function wherever you like, for example in route resolver, components, and etc. But in this example I’m just going to run it on the App Component just to show on how it works.

import { Post } from './models/posts.model';
import { Observable } from 'rxjs';
import { PostsStore } from './stores/posts.store';
import { Component, OnInit } from '@angular/core';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  posts$: Observable<Post[]>;

  constructor(
    private postsStore: PostsStore
  ) {
    this.postsStore.init();
  }

  ngOnInit() {
    this.posts$ = this.postsStore.getAll$();
  }
}

<div >
  <div >
    <ul *ngFor="let post of posts$ | async">
      <li>ID: {{ post.id }}</li>
      <li>TITLE: {{ post.title }}</li>
      <li>BODY: {{ post.body }}</li>
    </ul>
  </div>
</div>

.d-flex {
  display: flex;
}

.col {
  flex: 1;
}

We used an async pipe since our returned value is an observable but you can do it on the other way around where your going to subscribe to the observable then assign the returned value to your variable like the example below.

export class AppComponent implements OnInit {

  posts: Post[];

  constructor(
    private postsStore: PostsStore
  ) {
    this.postsStore.init();
  }

  ngOnInit() {
    this.postsStore.getAll$().subscribe(posts => {
      this.posts = posts;
    });
  }
}

<div >
  <div >
    <ul *ngFor="let post of posts">
      <li>ID: {{ post.id }}</li>
      <li>TITLE: {{ post.title }}</li>
      <li>BODY: {{ post.body }}</li>
    </ul>
  </div>
</div>

I would still prefer using async pipe as much as possible since it automatically unsubscribe the observable when the component is destroyed or not active but you can also manually unsubscribe the subscription however with extra codes.

Example Basic CRUD

import { Injectable } from '@angular/core';
import { tap } from 'rxjs/operators';
import { PostsService } from '../services/posts.service';
import { Store } from './store';
import { Post } from '../models/posts.model';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PostsStore extends Store<Post[]> {

  constructor(private postsService: PostsService) {
    super();
  }

  init = (): void => {
    if (this.getAll()) { return; }

    this.postsService.get$().pipe(
      tap(this.store)
    ).subscribe();
  }

  create$ = (post: Post): Observable<Post> => this.postsService
    .post$(post)
    .pipe(
      tap(resPost => {
        this.store([
          ...this.getAll(),
          {
            id: resPost.id,
            ...post
          }
        ]);
      })
    )

  update$ = (postId: number, post: Post) => this.postsService
    .patch$(postId, post)
    .pipe(
      tap(resPost => {
        const posts = this.getAll();
        const postIndex = this.getAll().findIndex(item => item.id === postId);
        posts[postIndex] = {
          id: resPost.id,
          ...post
        };

        this.store(posts);
      })
    )

  delete$ = (postId: number) => this.postsService
    .delete$(postId)
    .pipe(
      tap(() => {
        const posts = this.getAll();
        const postIndex = this.getAll().findIndex(item => item.id === postId);
        posts.splice(postIndex, 1);

        this.store(posts);
      })
    )
}

import { Post } from './models/posts.model';
import { Observable } from 'rxjs';
import { PostsStore } from './stores/posts.store';
import { Component, OnInit } from '@angular/core';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  posts$: Observable<Post[]>;

  constructor(
    private postsStore: PostsStore
  ) {
    this.postsStore.init();
  }

  ngOnInit() {
    this.posts$ = this.postsStore.getAll$();
  }

  createPost() {
    this.postsStore.create$({
      userId: 1,
      title: 'Codedam',
      body: 'Unlock Codes and It is Awsome'
    }).subscribe(post => {
      console.log(post);
    });
  }

  updatePost() {
    this.postsStore.update$( 1, {
      userId: 1,
      title: 'Codedam',
      body: 'Unlock Codes and It is Awsome'
    }).subscribe(post => {
      console.log(post);
    });
  }

  deletePost() {
    this.postsStore.delete$(1).subscribe(post => {
      console.log(post);
    });
  }
}

<div >
  <div >
    <ul *ngFor="let post of posts$ | async">
      <li>ID: {{ post.id }}</li>
      <li>TITLE: {{ post.title }}</li>
      <li>BODY: {{ post.body }}</li>
      <li>
        <button (click)="createPost()">Create</button>
        <button (click)="updatePost()">Update</button>
        <button (click)="deletePost()">Delete</button>
      </li>
    </ul>
  </div>
</div>

So yeah! This is the end about Angular State Management and how to make yourself a Store without using any external libraries. If you have any questions or suggestions feel free to comment here and I will try to reply as soon as I can.

The post Angular State Management using BehaviorSubject appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Today I’ll demonstrate the use case of backreference in javascript regular expression. Well some of us, specially a beginner find it hard to learn regular expression and we don’t quite appreciate writing regular expression because of its complexity. But there are often times that writing a good regex would benefit us and save us time from developing application.

Okay enough of that. Let us assume that we have a problem that we need to solve. Suppose you have a string aaaccfgzzz and you want to match any consecutive characters in the string eg: aaa, cc and zzz.

Well, if I were to present my algorithm to solve the problem It would be like this:

const str = "aaaccfgzzz";
const obj = {};
for (let c of str) {
	if (obj[c]) {
		obj[c] += 1;
	} else {
		obj[c] = 1;
	}
}
const consecutiveStrings = Object.keys(obj)
		.filter(c => obj[c] > 1)
		.map(c => c.repeat(obj[c]));
console.log(consecutiveStrings); // output ["aaa", "cc", "zzz"]

I know there are lots of better solution than mine. But as you can see it requires a lot of typing to solve that problem.

Fortunately, with the help of our knowledge in regex backreference we would be able to solve the problem using only this code:

const str = "aaaccfgzzz";
console.log(str.match(/(.)\1+/g));
// output ["aaa", "cc", "zzz"]

Well, of course I will have to explain how the regex works. If you have a basic knowledge in regular expression and you know how capturing group works in regex then you can easily understand this regex or you might have already known it.

First we have this expression (.). The . expression simply matches any character in the string and captures the matched character with the ( and ) expression around the .. What those parenthesis (capturing group) do is to store any matched character into this regex expression \{n} which is called “backreference”. We put \1 there because there is only a single capturing group. If we have a second capturing group then we can use \2 expression and \3 for third capturing group and so on.

As you can see, the regex matches [‘aaa’, ‘cc’, ‘zzz’] and not any single character in the string because . expression matches the letter “a” in the string and the next letter “a” would be matched by the \1 expression which is being made available by the effect of capturing group that stores the matched character by the . expression. We also have the + expression after the . expression. What it does is to match one or more occurrences of \1(backreference). If we did not put the + expression there then the regex would match only 2 consecutive characters eg ['aa', 'cc', 'zz']. We also put g modifier there. It is used to perform a global match (find all matches rather than stopping after the first match).

Another example:

const str = "John Doe";
console.log(str.replace(/(\w+) (\w+)/, "$2 $1"));
// output "Doe John"

With this code we perform a reverse algorithm on the string with the use of regex backreference. The only difference is when we perform a replace the matched string would be stored into ${n} expression instead of \{n} and it would be available on the second parameter of the replace method.

Conclusion:

The backreference in regular expression is rarely used but it is a powerful tool that you must acquire because with that you can do a lot of string manipulation and I’m sure you would encounter that whenever you develop a quite complex application.

The post The power of backreference in javascript regular expression appeared first on Codedam.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Separate tags by commas
To access this feature, please upgrade your account.
Start your free month
Free Preview