Thursday, December 13, 2018

Concept of Immutability and How To Write Immutable Code

Immutability can be a confusing topic, and it pops up all over the place in React, Redux, and JavaScript in general.

What is Immutability?
First off, immutable is the opposite of mutable – and mutable means changeable, modifiable… able to be messed with. So something that is immutable, then, is something that cannot be changed.

While JavaScript isn’t a purely functional language, it can sorta pretend to be sometimes. Certain Array operations in JS are immutable (meaning that they return a new array, instead of modifying the original). String operations are always immutable (they create a new string with the changes).

Rules of Immutability
In order to be pure a function must follow these rules:
- A pure function must always return the same value when given the same inputs.
- A Pure functions can only call other pure functions.
- A pure function must not have any side effects.

JS Array Methods That Mutate
Certain array methods will mutate the array they’re used on:
- push (add an item to the end)
- pop (remove an item from the end)
- shift (remove an item from the beginning)
- unshift (add an item to the beginning)
- sort
- reverse
- splice

Immutable JS Methods (Instead of modifying array, it creates an entirely new one)
- The ... Spread Operator
- slice
- concat
- Object.assign

How To Update State in Redux
Redux requires that its reducers be pure functions. This means you can’t modify the state directly – you have to create a new state based on the old one. Writing code to do immutable state updates can be tricky.

Below examples make heavy use of the spread operator for arrays and objects. When this ... notation is placed before an object or array, it unwraps the children within, and inserts them right there. The spread operator makes it easy to create a new object or array that contains the exact same contents as another one. This is useful for creating a copy of an object/array, and then overwriting specific properties that you need to change.

These examples are written in the context of returning state from a Redux reducer. I’ll show what the incoming state looks like, and then show how to return an updated state. For the sake of keeping the examples clean, I’m gonna ignore the “action” parameter entirely. Pretend that this state update will happen for any action.

These examples will show what immutability is and how to write immutable code in your own apps.
- Update an Object
- Update an Object in an Object
- Updating an Object by Key
- Prepend an item to an array
- Add an item to an array
- Insert an item in the middle of an array
- Update an item in an array by index
- Update an item in an array with map
- Update an object in an array
- Remove an item from an array with filter

Update an Object
When you want to update the top-level properties in the Redux state object, copy the existing state with ...state and then list out the properties you want to change, with their new values.
function reducer(state, action) {
  /*
    State looks like:

    state = {
      clicks: 0,
      count: 0
    }
  */

  return {
    ...state,
    clicks: state.clicks + 1,
    count: state.count - 1
  }
}

Update an Object in an Object
When the object you want to update is one (or more) levels deep within the Redux state, you need to make a copy of every level up to and including the object you want to update. Here’s an example one level deep:
function reducer(state, action) {
  /*
    State looks like:

    state = {
      house: {
        name: "Ravenclaw",
        points: 17
      }
    }
  */

  // Two points for Ravenclaw
  return {
    ...state, // copy the state (level 0)
    house: {
      ...state.house, // copy the nested object (level 1)
      points: state.house.points + 2
    }
  }
Here’s another example, this time updating an object that’s two levels deep:
function reducer(state, action) {
  /*
    State looks like:

    state = {
      school: {
        name: "Hogwarts",
        house: {
          name: "Ravenclaw",
          points: 17
        }
      }
    }
  */

  // Two points for Ravenclaw
  return {
    ...state, // copy the state (level 0)
    school: {
      ...state.school, // copy level 1
      house: {         // replace state.school.house...
        ...state.school.house, // copy existing house properties
        points: state.school.house.points + 2  // change a property
      }
    }
  }

Updating an Object by Key
function reducer(state, action) {
  /*
    State looks like:

    const state = {
      houses: {
        gryffindor: {
          points: 15
        },
        ravenclaw: {
          points: 18
        },
        hufflepuff: {
          points: 7
        },
        slytherin: {
          points: 5
        }
      }
    }
  */

  // Add 3 points to Ravenclaw,
  // when the name is stored in a variable
  const key = "ravenclaw";
  return {
    ...state, // copy state
    houses: {
      ...state.houses, // copy houses
      [key]: {  // update one specific house (using Computed Property syntax)
        ...state.houses[key],  // copy that specific house's properties
        points: state.houses[key].points + 3   // update its `points` property
      }
    }
  }

Prepend an item to an array
Here is how you can add an item to the beginning of an array in an immutable way, suitable for Redux:
function reducer(state, action) {
  /*
    State looks like:

    state = [1, 2, 3];
  */

  const newItem = 0;
  return [    // a new array
    newItem,  // add the new item first
    ...state  // then explode the old state at the end
  ];
}

Add an item to an array
Here is how you can append an item to the end of an array, immutably:
function reducer(state, action) {
  /*
    State looks like:

    state = [1, 2, 3];
  */

  const newItem = 0;
  return [    // a new array
    ...state, // explode the old state first
    newItem   // then add the new item at the end
  ];
You can also make a copy of the array with .slice, and then mutate the copy:
function reducer(state, action) {
  const newItem = 0;
  const newState = state.slice();

  newState.push(newItem);
  return newState;
}

Update an item in an array with map
Array’s .map function will return a new array by calling the function you provide, passing in each existing item, and using your return value as the new item’s value.

In other words, if you have an array with N many items and want a new array that still has N items, use .map. You can update/replace one or more items with a single pass through the array.
function reducer(state, action) {
  /*
    State looks like:

    state = [1, 2, "X", 4];
  */

  return state.map((item, index) => {
    // Replace "X" with 3
    // alternatively: you could look for a specific index
    if(item === "X") {
      return 3;
    }

    // Leave every other item unchanged
    return item;
  });
}

Update an object in an array
This works the same way as above. The only difference is we’ll need to construct a new object and return a copy of the one we want to change.

Array’s .map function will return a new array by calling the function you provide, passing in each existing item, and using your return value as the new item’s value.

In other words, if you have an array with N many items and want a new array that still has N items, use .map. You can update/replace one or more items with a single pass through the array.

In this example we have an array of users with email addresses. One of them changed their email and we need to update it. I’ll show how the user’s ID and new email could come in as part of the action, but you can adapt this to accept the values from somewhere else of course (if you’re not using Redux, for instance).
function reducer(state, action) {
  /*
    State looks like:

    state = [
      {
        id: 1,
        email: 'jen@reynholmindustries.com'
      },
      {
        id: 2,
        email: 'peter@initech.com'
      }
    ]

    Action contains the new info:

    action = {
      type: "UPDATE_EMAIL"
      payload: {
        userId: 2,  // Peter's ID
        newEmail: 'peter@construction.co'
      }
    }
  */

  return state.map((item, index) => {
    // Find the item with the matching id
    if(item.id === action.payload.userId) {
      // Return a new object
      return {
        ...item,  // copy the existing item
        email: action.payload.newEmail  // replace the email addr
      }
    }

    // Leave every other item unchanged
    return item;
  });
}

Insert an item in the middle of an array
Array’s .splice function will insert an item, but it will also mutate the array.

Since we don’t want to mutate the original, we can make a copy first (with .slice), then use .splice to insert an item into the copy.

The other way to do this involves copying in all the elements BEFORE the new one, then inserting the new one, and then copying in all the elements AFTER it. It’s easy to get the indices wrong though.
function reducer(state, action) {
  /*
    State looks like:

    state = [1, 2, 3, 5, 6];
  */

  const newItem = 4;

  // make a copy
  const newState = state.slice();

  // insert the new item at index 3
  newState.splice(3, 0, newItem)

  return newState;

  /*
  // You can also do it this way:

  return [                // make a new array
    ...state.slice(0, 3), // copy the first 3 items unchanged
    newItem,              // insert the new item
    ...state.slice(3)     // copy the rest, starting at index 3
  ];
  */
}

Update an item in an array by index
We can use Array’s .map to return a new value for a specific index, and leave the other elements unchanged.
function reducer(state, action) {
  /*
    State looks like:

    state = [1, 2, "X", 4];
  */

  return state.map((item, index) => {
    // Replace the item at index 2
    if(index === 2) {
      return 3;
    }

    // Leave every other item unchanged
    return item;
  });
}

Remove an item from an array with filter
Array’s .filter function will call the function you provide, pass in each existing item, and return a new array with only the items where your function returned "true". If you return false, that item gets removed.

If you have an array with N items and you want to end up with fewer items, use .filter.
function reducer(state, action) {
  /*
    State looks like:

    state = [1, 2, "X", 4];
  */

  return state.filter((item, index) => {
    // Remove item "X"
    // alternatively: you could look for a specific index
    if(item === "X") {
      return false;
    }

    // Every other item stays
    return true;
  });
}


For detail explanation and more, please visit Immutability in React and Redux: The Complete Guide by Dave Ceddia.

Monday, December 3, 2018

GIT - The Simple Guide

Just a simple guide for getting started with git. It shows how to use terminal or command lines to create, add, commit, branching, tags etc easily by following simple guides described as following.

Create a new repository
create a new directory, open it and perform a
  git init
to create a new git repository.

Checkout a repository
Create a working copy of a local repository by running the command
  git clone /path/to/repository
when using a remote server, your command will be
  git clone username@host:/path/to/repository

Workflow
Your local repository consists of three "trees" maintained by git. the first one is your Working Directory which holds the actual files. the second one is the Index which acts as a staging area and finally the HEAD which points to the last commit you've made.

Add & commit
You can propose changes (add it to the Index) using
 git add <filename>
 git add *
This is the first step in the basic git workflow. To actually commit these changes use
 git commit -m "Commit message"
Now the file is committed to the HEAD, but not in your remote repository yet.

Pushing changes
Your changes are now in the HEAD of your local working copy. To send those changes to your remote repository, execute
git push origin master
Change master to whatever branch you want to push your changes to.
If you have not cloned an existing repository and want to connect your repository to a remote server, you need to add it with
git remote add origin <server>
Now you are able to push your changes to the selected remote server

Branching
Branches are used to develop features isolated from each other. The master branch is the "default" branch when you create a repository. Use other branches for development and merge them back to the master branch upon completion.

create a new branch named "feature_x" and switch to it using
git checkout -b feature_x
switch back to master
 
 git checkout master
and delete the branch again.
 git branch -d feature_x
A branch is not available to others unless you push the branch to your remote repository
 git push origin <branch>

Update & merge
To update your local repository to the newest commit, execute
git pull
in your working directory to fetch and merge remote changes.
To merge another branch into your active branch (e.g. master), use
git merge <branch>
in both cases git tries to auto-merge changes. Unfortunately, this is not always possible and results in conflicts. You are responsible to merge those conflicts manually by editing the files shown by git. After changing, you need to mark them as merged with
 git add <filename>
before merging changes, you can also preview them by using
 git diff <source_branch> <target_branch>

Tagging
Tt's recommended to create tags for software releases. this is a known concept, which also exists in SVN. You can create a new tag named 1.0.0 by executing
git tag 1.0.0 1b2e1d63ff
the 1b2e1d63ff stands for the first 10 characters of the commit id you want to reference with your tag. You can get the commit id by looking at the...

Replace local changes
In case you did something wrong, which for sure never happens ;), you can replace local changes using the command
 git checkout -- <filename>
this replaces the changes in your working tree with the last content in HEAD. Changes already added to the index, as well as new files, will be kept.
If you instead want to drop all your local changes and commits, fetch the latest history from the server and point your local master branch at it like this
 git fetch origin
 git reset --hard origin/master

Source : git - the simple guide

Monday, November 26, 2018

How To Upgrade Node.js To The Latest Version?

If you initially installed Node.js with Homebrew, run:
 brew update
 brew upgrade node
 npm update -g npm

Other Alternatives:
A convenient way to change versions is to use nvm:
 brew install nvm
To install the latest version of Node.js with nvm:
 nvm install node
Upgrading via NPM
You can use the simpler method via the terminal. Avoid using sudo unless you need to.
 sudo npm cache clean -f
 sudo npm install -g n
Then
 sudo n stable 
Or
 sudo n latest
After which you may opt to confirm the upgrade
 node -v

Tuesday, July 3, 2018

Using Axios In the Loop With Async/Await Promise

With Babel now supporting async/await out of the box, and ES2016 (or ES7) just around the corner, more and more people are realizing how awesome this pattern is for writing asynchronous code, using synchronous code structure.

Async/await
1. Every async function you write will return a promise, and every single thing you await will ordinarily be a promise.
2. Async/await is a new way to write asynchronous code.
3. Async/await is actually built on top of promises. It cannot be used with plain callbacks or node callbacks.
4. Async/await is, like promises, non blocking.
5. Async/await makes asynchronous code look and behave a little more like synchronous code. This is where all its power lies.

In the following example we are using Axios to fetch the data and using for loop with Async/Await promise to print the title of the posts. The result is sequentially logged one by one after each Promise resolved.
const axios = require('axios');

const getTitle = (num) => {
  return new Promise((resolve, reject) => {
    axios.get(`https://jsonplaceholder.typicode.com/posts/${num}`)
    .then(response => {
      return resolve(response.data.title)
    })
    .catch(error => {
      return reject(error.message)
    })
  })
}

const start = async() => {
  for (let num of [1, 2, 3, 4, 5]) {
    await getTitle(num).then((title) => {
      console.log(`num ${num}: ${title}`);
    })
  }
  console.log('Done');
}

start();

//Output 
// ---
// num 1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
// num 2: qui est esse
// num 3: ea molestias quasi exercitationem repellat qui ipsa sit aut
// num 4: eum et est occaecati
// num 5: nesciunt quas odio
// Done

Some things to note:
1. Our function has the keyword async before it. The await keyword can only be used inside functions defined with async. Any async function returns a promise implicitly, and the resolve value of the promise will be whatever you return from the function (which is the string "response.data.title" in our case).
2. await getTitle(num) means that the console.log call will wait until getTitle(num) promise resolves and print it value.

References:
6 Reasons Why JavaScript’s Async/Await Blows Promises Away
Loop with async and await in JavaScript

Friday, April 27, 2018

How To Load HTML5 Video After Video Ends and Set Controls List Attribute In React?

In modern browsers, adding a video to your page is as easy as adding an image. I am not going on detail on how HTML5 Video works.

It is very easy to add HTML5 video in React. React DOM now supports these media events on audio and video tags: onAbort, onCanPlay, onCanPlayThrough, onDurationChange, onEmptied, onEncrypted, onEnded, onError, onLoadedData, onLoadedMetadata, onLoadStart, onPause, onPlay, onPlaying, onProgress, onRateChange, onSeeked, onSeeking, onStalled, onSuspend, onTimeUpdate, onVolumeChange, onWaiting.

In this tutorial, you can see how to add HTML5 video tag controlsList attribute in React and how to load the video to the beginning of the video or start frame again after video has ended.

componentDidMount() {
  document.querySelectorAll('video')
  .forEach( x => x.setAttribute("controlsList","nodownload noremoteplayback"));
}

onVideoEnded = (index) => {
   var video = document.querySelector('#video'+index);
   video.load();
}

return (
  <video id="video1" controls muted src="https://example.com/video.mp4" 
  onEnded={() => this.onVideoEnded('1') />
);

These are only some of used properties, event and method of HTML5 Video in this article. For more details, please visit HTML5 Video.

Attributes
controls => Shows the default video controls (play, pause, etc).
muted => Mutes the audio from the video
Used Event
onEnded => Fired when the video has finished playing
Used Method
load() => method loads the video and reset the play head to the beginning of the video

Wednesday, January 31, 2018

How To Update To The Latest Node.js Version On a Mac?

N is an npm-based node version manager. You can install it by installing first some version of node and then running
 npm install -g n
Assuming you have successfully installed n. The following will install the latest version of node.
 sudo n latest
Latest version by the time the article was published: v9.4.0

You can use Nvm or Homebrew as well.