{"id":16347931,"url":"https://github.com/iroy2000/immutablejs-for-beginners","last_synced_at":"2025-11-09T04:30:34.288Z","repository":{"id":110777945,"uuid":"69187780","full_name":"iroy2000/immutablejs-for-beginners","owner":"iroy2000","description":"This documentation is trying to help people who starts using FB immutable.js but at the same time feeling confused by the original documentation","archived":false,"fork":false,"pushed_at":"2018-03-15T20:45:11.000Z","size":11,"stargazers_count":24,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-28T06:25:23.733Z","etag":null,"topics":["documentation","immutablejs"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iroy2000.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-25T20:08:24.000Z","updated_at":"2023-08-22T15:32:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"2c2fb26e-5741-4d2b-9423-4e1ed0e499a9","html_url":"https://github.com/iroy2000/immutablejs-for-beginners","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iroy2000%2Fimmutablejs-for-beginners","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iroy2000%2Fimmutablejs-for-beginners/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iroy2000%2Fimmutablejs-for-beginners/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iroy2000%2Fimmutablejs-for-beginners/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iroy2000","download_url":"https://codeload.github.com/iroy2000/immutablejs-for-beginners/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239567174,"owners_count":19660425,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["documentation","immutablejs"],"created_at":"2024-10-11T00:47:09.802Z","updated_at":"2025-02-18T23:25:28.078Z","avatar_url":"https://github.com/iroy2000.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Immutable.js for beginners\n\nThis documentation is trying to help people who start using [immutable.js](https://facebook.github.io/immutable-js/) but at the same time feeling confused by the original overwhelming documentation.  \n\n**Worth Mentioning:** The documentation syntax of [immutable.js](https://facebook.github.io/immutable-js/) is written with [Typescript](http://www.typescriptlang.org/docs/handbook/basic-types.html), so if you are confused, it is not your fault :)\n\n**If you are looking for basic concepts**, please look at the last section `Resources`, I put up a few links to hook you up with some important concepts in Immutable / Immutablejs.\n\n\n## Join our conversation for Immutable.js for beginners on [Slack](https://immutablejs4beginners.slack.com/)\n\n## Table of Contents\n* [Map](#map)\n* [List](#list)\n* [Other Data Structure](#other-data-structure) (Set, Record, Seq)\n* [Resources](#resources)\n* [Contributions](#contributions)\n\n## Map\n\nAssume:\n\n* you have imported your immutablejs somewhere  \n* and, you have the following data structure\n\n```javascript\nimport { Map } from 'immutable'\n\nlet me = Map({\n  name: 'roy',\n  hobby: 'reading'\n})\n```\n\nThe following will showcase basic operations for map\n\n```javascript\nme.name // undefined, you can't reference the properties directly\nme.get('name') // roy\n\nme.set('name', 'iroy2000') // setting values\nme.get('name') // roy ( what ??? )\n\n// !!! Remember in immutable.js when you \"mutate\" the data, \n// it does not modify the original value, but it will return a new one\n// -----------------------------------------------------------------------\n\nme = me.set('name', 'iroy2000') // setting values\nme.get('name') // iroy2000 ( ah !!! )\n\nme = me.update('name', item =\u003e item.toUppercase)\nme.get('name') // IROY2000\n```\n\nThe following to show case you can merge with a plain object\n\n```javascript\nlet map2 = Map({\n  age: '\u003e 20'\n})\n\nlet mapPlainObject = {\n  gender: 'male'\n}\n\n// ImmutableJS treat JavaScript Array or Object as an Iterable\n// ----------------------------------------------------------------\nme.merge(map2, mapPlainObject)  // now the map includes age and gender: { \"name\": \"IROY2000\", \"hobby\": \"reading\", \"age\": \"\u003e 20\", \"gender\": \"male\" }\n```\n\n**Equality Checking**\n\nNote that the equality checking is applied to not just Map only but to others as well.\n\nAssume that you have the following data structure\n\n```javascript\nimport { Map } from 'immutable'\n\nlet config = {\n  name: 'roy',\n  hobby: 'reading'\n}\n\nlet me1 = Map(config)\n\nlet me2 = Map(config)\n\n\nme1 == me2 // false\nme1.equals(me2) // true\n\n\n// If you just want to compare if they have same keys\n// ----------------------------------------------------------------\nmap2.keySeq().equals(me.keySeq())\n\n```\n\n**Note:** If you don't understand what is Iterable, it is a collection of objects that allow you to iterate through ( or loop through ) with functions like `map()`, `filter()` or native js `for ... in`.  Here is the official documentation in immutablejs on [Iterable](https://facebook.github.io/immutable-js/docs/#/Iterable), and here is a [StackOverflow](http://stackoverflow.com/questions/18884249/checking-whether-something-is-iterable) link if you need more insight.\n\n\nThe following showcase some common cases for a map\n\n```javascript\n\nmap1.has(['name'])  // true\n\nmap1.map((value, key) =\u003e `$value is cool`)\n\n```\n\n**Dealing with Nested structure**\n\nAssume you have the following structure for your map\n\n```javascript\n// The following show case you can create immutable data struture \n// directly from plain js object using fromJS helper function\n// Just remember \"array\" -\u003e \"List\" while \"object\" --\u003e \"Map\"\n// ----------------------------------------------------------------\n\nimport { fromJS } from 'immutable'\n\nlet me = fromJS({\n  name: 'roy',\n  profile: {\n    gender: 'male',\n    language:'javascript'\n  }\n})\n```\n\nThe following will explain how to performing deep values getting / setting\n\n```javascript\nme = me.setIn(['profile', 'language'], 'awesome javascript')\n\n// The following two \"gets\" are the same\n// ------------------------------------------\nme.get('profile').get('language') // awesome javascript\nme.getIn(['profile', 'language']) // awesome javascript\n\nme = me.mergeDeep({\n  profile : {\n    hobby: 'reading'\n  }\n})\n\nme.getIn(['profile', 'hobby'])  // reading\n\nme = me.updateIn(['profile', 'hobby'], item =\u003e .toUpperCase())\n\nme.getIn(['profile', 'hobby'])  // READING\n\n// The following will grab the profile data\n// and delete the key = \"hobby\" entry in it\n// -------------------------------------------\nme.updateIn(['profile'], profile =\u003e profile.delete('hobby'))\n\n```\n\n**Note** `fromJS` is a convenience function that convert nested Objects and Arrays into immutable `Map` and `List` automatically. So if you are using `fromJS`, **do not** apply or mix `Map` or `List` as you could introduce unintentional bugs.\n\n\n## List\n\n#### Assume you have the following data structure\n\nIn immutable.js, most of the data structure shares a lot of the same functionalities, because they are inheriting from the same data structure - [Iterable](https://facebook.github.io/immutable-js/docs/#/Iterable)\n\n\nIt supports javascript array-like operations, for example, `pop`, `push`, `concat`, `shift` ...\n\n```javascript\nimport { List } from 'immutable'\n\nlet items = List([1,2,3,4])\n\nitems = items.push(5)  // 1,2,3,4,5\n\nitems = items.pop() // 1,2,3,4\n\nitems = items.concat(5, 6)  // 1,2,3,4,5,6\n\nitems = items.shift() // 2,3,4,5,6\n\n```\n\n\n```javascript\nimport { fromJS } from 'immutable'\n\n\n// Remember \"array\" -\u003e \"List\" while \"object\" --\u003e \"Map\"\n// ------------------------------------------------------\n\nlet me = fromJS({\n  name: 'roy',\n  friends: [\n    { \n      name: 'captain america',\n      properties: {\n        equipment: 'shield'\n      }\n    },\n    { \n      name: 'iron man',\n      properties: {\n        equipment: 'armor'\n      } \n    },\n    { \n      name: 'thor',\n      properties: {\n        equipment: 'hammer'\n      }\n    }\n  ]\n})\n\n```\n\n```javascript\nme.get('friends').get(0).get('name') // captain america\nme.getIn(['friends', 0, 'name']) // captain america\n\nme.get('friends').get(0).get('properties').get('equipment')  // shield\nme.getIn(['friends', 0, 'properties', 'equipment']) // shield\n\n\nme = me.setIn(['friends', 0, 'properties', 'equipment'], 'glove');\n\nlet hulk = {\n  name: 'hulk',\n  properties: {\n    equipment: 'body'\n  } \n}\n\n// now you have new friends\nme = me.update('friends', friends =\u003e friends.push(hulk))\n\n\nlet friendYouWantToKnowTheIndex = me.get('friends').findIndex(friend =\u003e {\n return friend.get('name') === 'captain america' \n})\n\nme = me.setIn(['friends', friendYouWantToKnowTheIndex, 'equipment'], 'shield')\n\n// How about shuffling all your friends ?\n// A better version would be a custom comparator\n// -----------------------------------------------\nlist = me.update('friends', \n    friends =\u003e friends.sortBy(() =\u003e Math.random())\n)\n```\n\nThe following show case some common use case for a List\n\n```javascript\nlet heroSalaryList = Immutable.List([\n  {name: 'Thor', salary: 1000},\n  {name: 'Iron Man', salary: 500},\n  {name: 'Hawkeye', salary: 300}\n])\n\n// Iterate through the list and reduce the list to a value\n// For example, add all salaries of heroes \n// ( and divide by number of heroes )\n// ----------------------------------------------------------\nlet averageSalary = heroSalaryList.reduce((total, hero) =\u003e {   \n  return total + hero.salary\n}, 0) / heroSalaryList.count()\n\naverageSalary == 600 // true\n\n// fitler the list whose salary cannot be divided by 500\n// ----------------------------------------------------------\nlet filteredHeroSalaryList = heroSalaryList.filter(\n  hero =\u003e hero.salary % 500 \u003e 1\n)\n\nfilteredHeroSalaryList.count() // only 1 left\n\nfilteredHeroSalaryList.get(0).get('name') // Hawkeye\n\n```\n\n## Other Data Structure\n\n#### Set\nAn array ( or iterable type ) of unique elements and it will remove any duplicates.\n\n```javascript\nimport { Set } from 'immutable'\n\nlet set1 = Set([1,1,2,2,3,3])\n\nset1.count() // 3\nset1.toArray() // 1,2,3\n\n// You can perform subtract, intersect and union on a set.\n// But if your set is objects, in order to do that safely, \n// you will have to create variables before creating the set.\n\nconst set2 = Set(['hello', 'world', 'what', 'up']);\n\nset2.subtract['hello']  // it will remove the value from the set\n\n// consider the following case, which the set contains objects\nconst greet1 = { 'hello': 'world' };\nconst greet2 = { 'what': 'up' };\n\nconst greetSet = Set([greet1, greet2]);\n\ngreetSet.subtract([{'hello': 'world'}]);  // !!! It won't work !!!\n\ngreetSet.subtract([greet1]);  // It will work\n\n```\n\n#### Record\nRecord let you create a javascript class that comes with default values.\n\n```javascript\nimport { Record } from 'immutable'\n\nlet Villian = Record({ \n   skill: 'do very bad thing'\n})\n\nlet joker = new Villian({\n  skill: 'playing poker'\n})\n\njoker.toJSON() // { skill: 'playing poker' }\n\n// It will fall back to default value\n// if you remove it\n// -----------------------------------------------\njoker = joker.remove('skill')  \n\njoker.toJSON() // { skill: 'do very bad thing' }\n\n// Values provided to the constructor not found \n// in the Record type will be ignored.\n// -----------------------------------------------\n\nlet batwoman = new Villian({\n  hairstyle: 'cool'\n})\n\nbatwoman.toJSON() // { skill: 'do very bad thing' }\n\n```\n\n#### Seq ( Lazy Operation )\nLazy operation means that the chain methods ( operations ) are not executed until it is requested. And it will stop the execution when the returned items fulfill the request.\n\n```javascript\nimport { Seq } from 'immutable'\n\n\n// Note: The order of the items are important\n// ------------------------------------------------------------------\nvar femaleHero = Seq.of(\n\t  {name:'thor', gender: 'male'},\n\t  {name:'hulk', gender: 'male'},\n\t  {name:'black widow', gender: 'female'}\n\t)\n    .filter(hero =\u003e hero.gender == 'female')\n    .map(hero =\u003e `${hero.name} is a ${hero.gender}`)\n                              \n\n// Only performs as much work as necessary to get the result\n// ------------------------------------------------------------------\nfemaleHero  // Nothing will be called\n\n// This will iterate all three items until the \n// first \"true\" return.  All three hero are iterated\n// util we found one \"female hero\" to return.\n// ------------------------------------------------------------------\nfemaleHero.get(0)  // return 'black widow is a female'\n\n\n// If we change the order of the Seq, the first \"true\" will\n// return and the rest of the operations will not even get called.\n//\n// For example: \n// The request of getting first \"female hero\" is fulfilled,\n// the progrm terminates, which means the next operation of \n// `filter()` and `map()` will not even get called.\n// ------------------------------------------------------------------\n\n{name:'black widow', gender: 'female'},\n{name:'thor', gender: 'male'},\n{name:'hulk', gender: 'male'}\n\n```\n\n\n## Resources\n\n#### Readings\n* [Introduction to Immutablejs](https://auth0.com/blog/intro-to-immutable-js/)\n* [Immutablejs overview](http://www.darul.io/post/2015-07-06_immutablejs-overview)\n\n#### Toolings\n* [Immutable live tutorial](http://blog.klipse.tech/javascript/2016/03/30/immutable.html)\n* [immutable-docs](http://brentburg.github.io/immutable-docs/api)\n\n## Contributions\n**Pull Request are welcomed !!!** Hopefully it will be a **community driven** effort to make other developers' life easier when learning immutable.js \n\n***PR*** could include more examples, better introduction, presentations, resources ... etc.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firoy2000%2Fimmutablejs-for-beginners","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firoy2000%2Fimmutablejs-for-beginners","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firoy2000%2Fimmutablejs-for-beginners/lists"}