Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Zvonár committed Feb 15, 2018
1 parent 106122c commit 70eb6d4
Show file tree
Hide file tree
Showing 6 changed files with 416 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ typings/
# dotenv environment variables file
.env

.DS_Store
.idea
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
language: node_js

notifications:
email:
on_success: never

node_js:
- stable

install:
- npm install

script:
- npm run cover

# Send coverage data to Coveralls
after_script: "cat coverage/lcov.info | node_modules/coveralls/bin/coveralls.js"
104 changes: 102 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,102 @@
# deleteIn
Deletes value from object according to provided path
deleteIn [![Build Status](https://travis-ci.org/mzvonar/deleteIn.svg?branch=master)](https://travis-ci.org/mzvonar/deleteIn) [![Coverage Status](https://coveralls.io/repos/github/mzvonar/deleteIn/badge.svg?branch=master)](https://coveralls.io/github/mzvonar/deleteIn?branch=master) [![npm version](https://badge.fury.io/js/%40mzvonar%2Fdeletein.svg)](https://badge.fury.io/js/%40mzvonar%2Fdeletein)
=========

Sets value in object by path. Path can be string or array (e.g. ['user', 'profile', 'gender']).
If any part of path doesn't exist it is created. Always returns new copy of object.

## Installation

`npm install @mzvonar/setin`

## Parameters
```javascript
setIn(context, path, value, push);
```

| Name | Description |
| - | - |
| ```context``` | Object in which the value will be set |
| ```path``` | Must be Array or String. See usage |
| ```value``` | Value to set in path |
| ```push``` | Whether to push the value to Array. See usage |

## Usage

```javascript
import setIn from '@mzvonar/setin';

const context = {
user: {
profile: {
gender: 'female'
}
}
};

const newContext = setIn(context, ['user', 'profile', 'gender'], 'male');
```

returns:
```javascript
{
user: {
profile: {
gender: 'male'
}
}
}
```

```javascript
const newContext = setIn(context, ['user', 'profile', 'address', 'country'], 'slovakia');
```

returns:
```javascript
{
user: {
profile: {
gender: 'male',
address: {
country: 'slovakia'
}
}
}
}
```

### Push
If fourth parameter is ```true``` and last item in path is ```Array``` value is pushed to the Array

example:
```javascript
const context = {
user: {
name: 'Mike',
nicknames: [
'terminator',
'maverick'
]
}
};

const newContext = setIn(context, ['user', 'nickanmes'], 'vincent vega');

console.log(newContext);
/*
{
user: {
name: 'Mike',
nicknames: [
'terminator',
'maverick',
'vincent vega'
]
}
}
*/
```

## Tests

`npm test`
76 changes: 76 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Deletes value in object according to provided path
* @param {Object} context
* @param {Array|string} path
* @return {Object} Copy of object with value at path deleted
*/

function createDeleteIn(mutable) {
return function deleteIn(context, path) {
if(!path) {
throw new Error('Path is undefined');
}

const pathType = Object.prototype.toString.call(path);
if(pathType !== '[object Undefined]' && pathType !== '[object Array]') {
path = [path];
}
else {
path = [].concat(path);
}

var currentPathPart = path.shift();

if(typeof currentPathPart === 'undefined' || currentPathPart === null) {
throw new Error('Path part is undefined');
}

if(!context) {
throw new Error('Context or it\'s part is undefined');
}

// var currentValue = path.length === 0 ? value : deleteIn(context[currentPathPart], path, value, push);

var contextType = Object.prototype.toString.call(context);
if(contextType === '[object Array]') {
var copy = mutable ? context : [].concat(context);

if(path.length === 0) {
if(typeof currentPathPart !== 'number') {
throw new Error('Trying to delete from Array with index type ' + typeof currentPathPart);
}
if(currentPathPart < 0) {
throw new Error('Trying to delete index ' + currentPathPart + ' which si lower than zero');
}
if(currentPathPart >= context.length) {
throw new Error('Trying to delete index ' + currentPathPart + ' which is greater than array length');
}

copy.splice(currentPathPart, 1);
}
else if(typeof copy[currentPathPart] !== 'undefined') {
copy[currentPathPart] = deleteIn(copy[currentPathPart], path);
}

return copy;
}
else if(contextType === '[object Object]') {
var copy = mutable ? context : Object.assign({}, context);

if(path.length === 0) {
delete copy[currentPathPart];
}
else if(typeof copy[currentPathPart] !== 'undefined') {
copy[currentPathPart] = deleteIn(copy[currentPathPart], path);
}

return copy;
}
else {
throw new Error('Trying to add property to ' + contextType);
}
};
}

module.exports = createDeleteIn();
module.exports.mutableDeleteIn = createDeleteIn(true);
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@mzvonar/deletein",
"version": "0.0.1",
"description": "Deletes value in object according to provided path and returns copy of object",
"main": "index.js",
"scripts": {
"test": "mocha",
"cover": "node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha -- -R spec test/*"
},
"keywords": [
"deleteIn",
"delete",
"in",
"copy",
"immutable"
],
"author": "Martin Zvonar <riffmaker@gmail.com> (martinzvonar.sk)",
"license": "MIT",
"devDependencies": {
"coveralls": "2.13.1",
"expect": "1.20.2",
"istanbul": "0.4.5",
"mocha": "3.4.2"
}
}

0 comments on commit 70eb6d4

Please sign in to comment.