rhalff / dot-object Goto Github PK
View Code? Open in Web Editor NEWTransform json objects using dot notation
License: MIT License
Transform json objects using dot notation
License: MIT License
I'm trying to convert an object to dot notation with dot.dot by running
const target = dot.dot({
a: 1,
b: 2,
c: {
d: 3,
e: {
f: 4,
},
},
})
Expected result
{
a: 1,
b: 2,
'c.d': 3,
'c.e.f': 4,
}
But when i'm logging target
it always result in the default object, nothing happens.
I'm using version 2.1.4.
It would be useful to find a way to copy the fields not present in the recipe
object to the target object.
This way, if I have an object with 20 properties and I need to change only 5, I can make a recipe with only five entries.
This could be achieved with five move
operations, but it's not that powerful.
An extra parameter in the transform function of maybe a final wildcard in the recipe could do the job, something like
const recipe = {
'p_key': 'email',
's_key': 'name',
'*': '*'};
Hi i'd like to transform the keys of each object contained in an array. I use keepArray, but the items are kept without transformation. You can find attached
Actual outcome
If i modify this line of code, doing a map over obj[key], I can get the expected result. Can it be a solution?
If yes, how long would it take to be released?
If not, do you have any suggestion?
I like your library, and our team are going to use it in a production project.
Thanks a lot for sharing it
In node console:
> require('dot-object').dot({hello: []})
{}
> require('dot-object').dot({hello:['world']})
{ 'hello.0': 'world' }
> require('dot-object').dot({hello:{}})
{}
>
Should be:
> require('dot-object').dot({hello:{world:[1]}})
{ 'hello.world.0': 1 }
> require('dot-object').dot({hello:{world:[]}})
{ 'hello.world': [] }
I am trying to set value for an existing object like this
var sampleObject = {
sample : {
dotted : {
bar: {
baz: 'baz'
}
}
}
}
dot.str('sample.dotted.bar',{baz:'boom'},sampleObject)
And it returns an error saying Trying to redefine non-empty obj['bar']
Adding a license property would help those using automated license managers in their software who also use dot-object.
Please see: #54
The idea is to make configurable array indexes output format. I want to convert object
some: { array: ['A', 'B'] }
like this
"some.array[0]": "A", "some.array[1]": "B"
instead of
"some.array.0": "A", "some.array.1": "B"
May be it's possible to do now with some settings? If not, I want to submit a PR with this functionality.
Was hoping I'd get back what I started with...
var a = [{'id':'xxx'}];
console.log(dot.object(dot.dot(a)));
Object {
0: Object {
id: 'xxx'
}
}
I understand when dot.object() is called it knows nothing about the argument passed to dot.dot() and assuming properties are actually array indices just because they're ints might be problematic. But, if they're all ints and contiguous maybe it'd be a safe assumption?
https://codepen.io/ecarey/pen/owJLJO
Kudos on the library by the way. I appreciate your work.
It seems that the aim is to support them, but the actual function declaration and code does not support modifiers.
Is there a workaround for this?
Line 466 in 0c8a4d8
It seems you can't create a new attribute on the top/root level object. See the following node console session:
dot = require('dot-object')
> x = { a: 1 }
{ a: 1 }
> dot.str('b', 2, x)
{ a: 1 }
> x
{ a: 1 }
It only seems to work if you are adding/creating a nested attribute:
> x = { a: 1 }
{ a: 1 }
> dot.str('b', 2, x)
{ a: 1 }
> dot.str('b.c', 2, x)
{ a: 1, b: { c: 2 } }
I am trying to acheive the following:
var data = {
foo: [
{ text: 'bar1' },
{ text: 'bar2' }
]
};
console.log(dot.pick('foo[0].text', data)); // Expected result: 'bar1'
However, the current API does not support this. Are there any plans on implementing this feature?
If not, would a pull request for this feature be accepted?
A similar feature exists in Mongo's API: positional update
Object.keys(obj).forEach(function (k) {
^
TypeError: Cannot convert undefined or null to object
I think it'll be good if there was a filter to undefined and null objects in this function, i looked at the code, but there wasn't a filter.
Modifiers on root properties do not process the transformation
var dot = require('dot-object');
var row = {
'nr': 200,
'nested.nr': 200,
};
var mods = {
'nr': [val => val * 2],
'nested.nr': [val => val * 2]
};
dot.object(row, mods);
console.log(row);
Result:
{
nr: 200,
nested: {
nr: 400
}
}
Expected:
{
nr: 400,
nested: {
nr: 400
}
}
I saw that pick
can delete array elements in place, replacing them with null
. But is there a way to actually remove the element, changing the length of the array?
Is there a way to set/modify an existing value with this?
var tee = {
a: "hello",
b: {
b1: "goodbye",
b2: "so long",
b3: "adios"
}
}
dot.update("tee.b.b2", tee, "good riddance");
// yield
{
a: "hello",
b: {
b1: "goodbye",
b2: "good riddance",
b3: "adios"
}
}
Is this possible, or something like it?
If we look at dot notation with something like MongoDB we can reference properties within an array without saying that we specifically want an indexed copy
An example is that we could reference both of these values by using one key array.property
src = {
array: [
{ property: 1 },
{ property: 2 },
]
}
We could either detect that the value is an array and work the exact same way ( which would be nice )
Or we could specify that we want to reference all the values in the array, using something like array[].property
For the latter we could implement something along the lines of the following:
dot._copy = dot.copy
dot.copy = function(srcKey, tgtKey, src, tgt){
var split, parentKey, restKey, parent;
if(srcKey !== tgtKey){
return dot._copy(srcKey, tgtKey, src, tgt);
}
if(srcKey.indexOf('[]') === -1){
return dot._copy(srcKey, tgtKey, src, tgt);
}
split = srcKey.split('[]');
parentKey = split[0];
restKey = split.slice(1).join('[]');
parent = dot.pick(parentKey, src);
parent.forEach(function(value, index){
var key = parentKey + "[" + index + "]" + restKey;
dot.copy(key, key, src, tgt);
});
return tgt;
};
I didn't add any extra use cases except for if the keys are the same, but we could easily work around that
Here is a pen of it http://codepen.io/anon/pen/ZQrVGv
Is there support for variable names with dots in them? E.g.
In:
var obj = {
"i.am": {
"an.array": ['a']
}
};
Out:
{
"i": {
"am": {
"an.array": [
"a"
]
}
}
}
Maybe I'm missing something in the docs, or is there no such thing (yet?)
Am I doing something wrong below with regard to the delete
function? I am frazzled, so I probably am.
$ npm ls | grep dot-object
└─┬ [email protected]
$ node
> var dot = require('dot-object')
undefined
> dot.delete('a', {a: 1})
TypeError: dot.delete is not a function
> dot.remove('a', {a: 1})
1
$ node --version
v10.15.3
As an aside, there is no v1.9.0
or 1.9.0
tag, so that doesn't show up as a release on GitHub.
Currently pick does not work with proxies but maybe it could be extended like this:
index.js -
DotObject.prototype.pick
- if (obj && typeof obj === 'object' && key in obj) {
+ if (obj && typeof obj === 'object' && Object.getOwnPropertyNames(obj).includes(key)) {
It works in the case if the proxy defines ownKeys() or getOwnPropertyDescriptor(target, key) methods.
Or maybe it could be extended with an option flag for this case?
Transferring a key with a value of a Date into the dotted object will not return the original value. See below for the breakdown.
Our object which we run through dot.dot:
const obj = {
dates: {
first: new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)'),
second: 'Normal string'
}
};
const tgt = Dot.dot(obj);
Result:
{
'dates.second': 'Normal string'
}
Expected result:
{
'dates.first': Mon Oct 13 2014 00:00:00 GMT+0100 (BST),
'dates.second': 'Normal string'
}
Can i calculate data?
var obj = {
data: {
base: "2000",
add: "2000",
substract: "2000",
multiply: "2",
division: "2"
}
};
var aaaa = 'base+add-substract*multiply/division'
// which mean my expected is 2000+2000-2000*2/2=2000
Reading through some of the other issues, it seems this may be intended behavior. We have enabled the option to output brackets around array indices.
{
items: [
{
123: 'foo',
456: 'bar'
}
]
}
// dot.dot(obj)
{
'items[0].123': 'foo',
'items[0].456': 'bar'
}
But when you run that through dot.object()
, you don't get the original object. You get a sparse array instead.
{
items: [
[
...123 empty slots...
'foo',
...333 empty slots...
'bar'
]
]
}
Is there an option to use objects for .
in all cases, even when the key is an integer?
It would be nice if dot-object came with an ESM entrypoint as well as CJS.
When we use dot.object()
is there a way to force numeric values in string to be a field instead of a position from an array?
For example
{ "errors.1": "error1", "errors.2": "error2", "errors.3": "error3" }
becomes
{errors: ["error1", "error2", "error3"]}
but I want it to be
{errors: {"1": "error1", "2": "error2", "3": "error3"}}
First things first: I loved this lib!
Is there a way to add ImmutableJS into dot-object lib? I think it would be cool and would enhance the performance.
I just included the index.js
file on a client side file and it works great. Is there an official way to do this?
Cool library, thank you!
As a developer, I want to be able to pick a value from an object if the key contains dots.
// Node JS: 12.5.0
const dot = require('dot-object');
test('Can pick value with dotted key', () => {
const object = { 'foo.bar': 'baz' };
expect(dot.pick('foo.bar', object)).toBe('baz');
});
Currently, I am receiving undefined
instead of baz
.
Hi, I just found out that if you want to update a key in an object with dot.str you can't do that:
const original = {
a: 1,
b: 2
}
dot.str("a", "Some string", original)
// results in:
// {
// a: 1,
// b: 2
// }
But while updating a key in an object in an array it works perfectly fine:
const original = {
arr: [{
a: 1,
b: 2
}]
};
dot.str('arr.0.a', "Some string", original);
// results in:
// {
// arr: [{
// a: "Some string",
// b: 2
// }]
// }
I can imagine that you can update the key of an object in an array because the order might have changed and it could be an other object. It would be great to either do the same for both or console.warn if you try to this. This should also be in the docs.
Cheers
If I have
{
"c.d":"e",
"a":"b",
"b":"b",
}
and I run
var DJ = require("dot-object");
new DJ().object(x)
The entry becomes shuffled:
{ a: 'b', b: 'b', c: { d: 'e' } }
Is there a way to preserve the key order?
Hi,
This one has me scratching my head:
ENV Windows 10
git version 2.18.0.windows.1
node v12.16.1
[email protected]
Example script:
var dot = require("dot-object");
var basepath = process.cwd();
console.log(basepath);
And when I run the above script i get:
basedir=$(dirname "$(echo "$0" | sed -e 's,\,/,g')")
^^^^^^^
SyntaxError: missing ) after argument list
?[90m at wrapSafe (internal/modules/cjs/loader.js:1072:16)?[39m
?[90m at Module._compile (internal/modules/cjs/loader.js:1122:27)?[39m
?[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)?[39m
?[90m at Module.load (internal/modules/cjs/loader.js:1002:32)?[39m
?[90m at Function.Module._load (internal/modules/cjs/loader.js:901:14)?[39m
?[90m at Module.require (internal/modules/cjs/loader.js:1044:19)?[39m
?[90m at require (internal/modules/cjs/helpers.js:77:18)?[39m
at Object. (C:\AngularApps\eserv-web-common-1\apps\tr\src\assets\translations\ngx-translate-extract-csv-ircc.js:2:11)
?[90m at Module._compile (internal/modules/cjs/loader.js:1158:30)?[39m
?[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)?[39m
bring this to
{
items[0]: 'item1',
items[1]: 'item2'
}
{
items: ['item1', 'item2']
}
this one
{
items[]: 'item1',
items[]: 'item2'
}
{
items: ['item1', 'item2']
}
Hi, I want to replace all occurrences of the array or object. How to do this?
example::
var dot = require('dot-object');
var str_replacement = 'XXXX';
let inputData = {
order_status: 1,
orders: [
{
order_id: 'A001',
date: "10-10-2019"
},
{
order_id: 'A002',
date: "10-11-2019"
}
],
shipping: {
address: "9th main, 6th cross, jp nagar"
},
billing: {
name: "John",
address: "10th floor, abc road."
}
}
dot.str('order_status', str_replacement, inputData); // works fine
dot.str('shipping.address', str_replacement, inputData); // works fine
dot.str('orders[*].order_id', str_replacement, inputData); // does not work (I want to replace all order_id of the array with the given replacement value)
dot.str('billing.*', str_replacement, inputData); // does not work (I want to replace all child values of the object with the given replacement value)
console.log(JSON.stringify(inputData, null, 2));
Expected Result
{
"order_status": "XXXX",
"orders": [
{
"order_id": "XXXX",
"date": "10-10-2019"
},
{
"order_id": "XXXX",
"date": "10-11-2019"
}
],
"shipping": {
"address": "XXXX"
},
"billing": {
"name": "XXXX",
"address": "XXXX"
}
}
will be helpfull to have a CDN for dot-object
Is there any way i can convert an object back to dot notation
person:{
name: "xyz"
}
"person.name" = "xyz"
Hi,
Is it possible to convert the following back to an object in your example?
{
"id": "my-id",
"nes.ted.value": true,
"other.nested.stuff": 5,
"some.array.0": "A",
"some.array.1": "B"
}
or something like:
{
"id": "my-id",
"nes.ted.value": true,
"other.nested.stuff": 5,
"some.array[0]": "A",
"some.array[1]": "B"
}
to
var obj = {
id: 'my-id',
nes: { ted: { value: true } },
other: { nested: { stuff: 5 } },
some: { array: ['A', 'B'] }
};
Thank you.
Regards,
Riaan
e.g.
var dj = require('dot-object');
dj.move(...);
dj.object(...);
Array conversion is inconsistent with field.0
and field[0]
. Example:
const object = {}
const objectTwo = {}
dot.str('object.fields.0.subfield', 'value', object)
dot.str('object.fields.1.subfield', 'value1', object)
dot.str('object.fields[0].subfield', 'value', objectTwo)
dot.str('object.fields[1].subfield', 'value1', objectTwo)
console.log(object)
console.log(objectTwo)
Output:
As you can see, the first object is correct, the second one is not.
I think it would be useful to be able to select between pascal case and camel case naming when transforming objects with dot.object and dot.dot. My use case is I'm making an ASP.NET MVC app that needs to build configs for a JS widget framework and both expect different naming styles.
I think the following describes what I'm asking pretty well:
var inData = {
name: 'foo',
arrayData: [1,2,3,{nestedObject: 'foo'}],
nested: {
nestedFoo: 'foo',
nestedArrayData: [1,2,3,{nestedObject: 'foo'}]
}
}
//dot.dot(inData) outputs
{
name: 'foo',
'arrayData.0': 1,
'arrayData.1': 2,
'arrayData.2': 3,
'arrayData.3.nestedObject': 'foo',
'nested.nestedFoo': 'foo',
'nested.nestedArrayData.0': 1,
'nested.nestedArrayData.1': 2,
'nested.nestedArrayData.2': 3,
'nested.nestedArrayData.3.nestedObject': 'foo'
}
// The feature request. In some situations the following could be useful:
// dot.dot(inData) ->
{
name: 'foo',
arrayData: [1,2,3,{nestedObject: 'foo'}],
nested.nestedFoo: 'foo',
nested.nestedArrayData: [1,2,3,{nestedObject: 'foo'}]
}
I also tried setting useArray
to false but this is what I get after doing that:
{ name: 'foo',
'arrayData[object Object]0': 1,
'arrayData[object Object]1': 2,
'arrayData[object Object]2': 3,
'arrayData[object Object]3[object Object]nestedObject': 'foo',
'nested[object Object]nestedFoo': 'foo',
'nested[object Object]nestedArrayData[object Object]0': 1,
'nested[object Object]nestedArrayData[object Object]1': 2,
'nested[object Object]nestedArrayData[object Object]2': 3,
'nested[object Object]nestedArrayData[object Object]3[object Object]nestedObject': 'foo' }
Hello,
Thanks for this awesome library!
I was wondering if it was possible to implement a new option based on keepArray
.
My goal is to have a full dot-object but only keeping the last arrays (if this array doesn't have any other nested properties).
It would be super useful and I wish it worked like this at first :)
Or if you don't want to implement this option, could you help me to achieve it?
Thanks a lot!
It would be helpful to provide a keep
option that behaves like keepArray
, but in a more generic way:
const dot = new DotObject();
dot.keep = value => {
return !(typeof value === 'string');
};
I can open a PR, let me know!
Hello
Thank you for this package .
i found a bug in v1.3.0 with array dot notation
when
{
"a[0]": "...",
"a[1]": "...",
"a[2]": "...",
"a[3].b[0].c[0]": "...",
"a[3].b[0].c[1]": "..."
}
i hope
{
"a": [
"...",
"...",
"...",
{
"b": [
{
"c": [
"...",
"..."
]
}
]
}
]
}
but dot-object return
{
"a": [
"...",
"...",
"...",
{
"b": { <== not an array !
"0": {
"c": [
"...",
"..."
]
}
}
}
]
}
Thanks for your help
AMi44
Would be great if object
function do not mutate obj
parameter:
You can use Object.assign for this purpose in:
DotObject.prototype.object = function (obj, mods) {
var self = this
obj = Object.assign({}, obj); // prevent mutation
Object.keys(obj).forEach(function (k) {
var mod = mods === undefined ? null : mods[k]
// normalize array notation.
var ok = parsePath(k, self.seperator).join(self.seperator)
if (ok.indexOf(self.seperator) !== -1) {
self._fill(ok.split(self.seperator), obj, obj[k], mod)
delete obj[k]
} else if (self.override) {
obj[k] = _process(obj[k], mod)
}
})
return obj
}
Example:
const dot = require('dot-object')
const config = {
level1: {
key1: 'val1',
2222: {
key2: 'val2'
}
},
3333: {
key3: 'val3'
}
}
console.log('original:')
console.log(config)
console.log()
const dotConfig = dot.dot(config)
console.log('should be the same as original:')
console.log(dot.object(dotConfig))
Output shows:
original:
{
'3333': { key3: 'val3' },
level1: { '2222': { key2: 'val2' }, key1: 'val1' }
}
should be the same as original:
{
'3333': { key3: 'val3' },
level1: [ <2222 empty items>, { key2: 'val2' }, key1: 'val1' ]
}
I am reopening this issue after making comments to a closed issue
@rhalff rhalff you mention "it's better to solve it in your own code" but we don't always know the object schema.
Is it possible to implement the following?
const object = {
foo: {
bar: 'one'
},
'foo.bar': 'two',
'some': {
'other.node': {
is: 'three'
}
}
}
let value = dot.pick('some["other.node"].is', object);
// three
let value = dot.pick('some["foo.bar"]', object);
// two
let value = dot.pick('some.foo.bar', object);
// one
This is similar to what I would do in code, and it should cover scenarios where the property has spaces and characters that might be used as alternative separators https://github.com/rhalff/dot-object#using-a-different-separator
This could work interchangeably, even for non-dotted properties:
dot.pick('foo.bar', object) === dot.pick('["foo"]["bar"]', object)
dot.pick('["foo.bar"]', object) === object["foo.bar"]
Let's suppose the following dot object :
args.1_telnet_server="server"
args.2_name="username"
args.3_password="password"
args.4_commands="commands"
What is the expected result ?
Javascript gives an error when I try to set an object like this :
var obj = {'1_ciao' : "ciao"}
console.log(obj[1_ciao])
Instead the dot-object library returns this :
var args = dot.object(dottedArgs)
=>
[ '1_telnet_server': 'server',
'2_name': 'username',
'3_password': 'password',
'4_commands': 'commands' ]
A kind of array but that is not iterable. Anyway, I should order a set of keys like this in some way. If I try to use the keys without number (telnet_server, name , ...) the application returns args dot in this order: [commands, name, password, telnet_server] ... I expect the order that I gave with the number convention that I cannot use with JS. Do you have some advice ?
Thanks in advance
Let's assume I receive an object from a server like
{"FieldName.Items[0].Email": ["Invalid email"]};
This library provides a possibility to change values to invalid-email
.
May I process keys' values?
I'd like to normalize the case of keys to
{
fieldName: {
items: [
email: ["Invalid email"]
]
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.