Dexie : How to add to array in nested object - javascript

I am using Dexie IndexedDB wrapper and I am trying to add an object to an existing array which in inside a nested object. The structure looks similar to below
{
Name : 'John',
age : 33,
tags : {
skill: [{
first: '.NET',
second: 'JAVA',
third: [{special1:'sleep'},{special2:'eat'}]
}]
}
}
I have tried many way to push object special3:'run' to skill.third but without success. My last attempt looked something like this
const pathObject = {};
const fullPath = 'result.tags.skill[3].third';
pathObject[fullPath] = {special3:'run'};
db.inspections.update(id, pathObject);
The object is added outside and not inside the array 'third' something like below
{
Name : 'John',
age : 33,
tags : {
skill: [{
first: '.NET',
second: 'JAVA',
third: [{special1:'sleep'},{special2:'eat'}]
}]
skill[3]: {
third: {special3:'run'}
}
}
}
I wish to know if there a way to add to arrays in nested object using Dexie if not is there a way to achieve this using indexeddb. Help is appreciated as problem is been holding back progress

The easiest is to use Collection.modify() with a callback function to mutate your model:
db.inspections.where('id').equals(id).modify(x =>
x.tags.skill[0].third.push({special3:'run'}) );
If you want to use a keypath containing array items, it is also possible, as arrays can be looked at as objects with numeric keys:
db.inspections.update(id, {"tags.skill.0.third.3": {special3:'run'}});

Related

Javascript object remove nesting

I am have an object that looks like this in the console,
res.local.details > Object {role-details : {} }
so to access this I would need to do res.local.details['role-details']
Is is possible to make it so I can "explode" role-details into details so I can just do
res.locals.details
to access the attributes from role-details
Yes, objects in JS are mutable. If you want to reassign data from one part of your object to another, you can just do it like this:
const myObj = {
name: {
first: 'John',
last: 'Smith',
},
address: {
streetNo: '123',
streetName: 'Main St',
city: {
name: 'Exampletown'
}
}
}
myObj.address.city.name // resolves to Exampletown
myObj.address.city = myObj.address.city.name
myObj.address.city /// resolves to Exampletown
This can be done in several ways.
In this particular case, where details just has that one property, you can just do:
res.local.details = res.local.details['role-details'];
In a more generic situation, details might have other properties that you don't want to destroy with this operation. In that case you can use:
Object.assign(res.local.details, res.local.details['role-details']);
With this, res.local.details will keep all its properties (provided they don't have the same name as properties of role-details), including role-details (but which becomes kind of obsolete).
The same can be achieved with:
res.local.details = {...res.local.details, ...res.local.details['role-details']};

Add object to another object property in JS

obj={
cats:{name:"kitty",age:"8"}
}
I need to add {name:"nacy",age:"12"} to obj.cats how I can do that?
What I tried:
Object.assign({name:"nacy",age:"12"},obj.cats);
This doesn't do anything, when I console.log(obj) I got kitty only.
In the end I want when I console.log(obj.cats) to get this:
{name:"kitty",age:"8"}, {name:"nacy",age:"12"}
And I don't want to use arrays.
It would be advisable to read more the documentation on objects and arrays. object.cats should be an array. Correct usage:
let obj = {
cats: [
{name:"kitty",age:"8"}
]
};
obj.cats.push({name:"nacy",age:"12"})
//Now here, we have 2 elements of obj.cats
console.log(obj.cats)
If you want to use objects and replace obj.cats (as your example), you must first pass the existing object, and then the value to replace: Object.assign(obj.cats, {name:"nacy",age:"12"})
if you wanna add 'nacy' first you have change cats to become an array
(read more about array: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
it looks like this:
var obj={
cats:[{name:"kitty",age:"8"}]
}
and then 'push' or add 'nacy'
obj.cats.push({name:"nacy",age:"12"})
result :
{ cats: [ { name: 'kitty', age: '8' }, { name: 'nacy', age: '12' } ] }

Creating Dynamic Keys In Object

I am struggling to create dynamic nested keys in javascript. My problem is that I need to have a object like this
{
"grandGrandFather": 'A',
"firstGrandFather": {
name: "AA",
children: {
first: 'AAA',
children: {
first: "AAAA"
}
}
},
"secondGrandFather": {
name: "AB",
first: 'ABA',
children: {
first: "ABAA",
second: "ABAB"
}
}
},
"thirdGrandFather": {
name: "AC",
children: {
name: "ACA"
}
}
}
Here problem is that I need to fetch these data from somewhere and I need to create these values dynamically. The prop creation begins from the first level and goes upto fourth level. So my question is how can I create dynamic keys in JS. Also I know you can create dynamic keys in JS like this:
var obj = {
prop1: "a",
prop2: "b",
prop3:'c'
}
obj['prop4'] = 'd';
Also I have been successful in creating a props to a level but when I need to stack these I get confused any help would be appreciated.
Further details about above object
In the above object I created I am getting data from database and I need to add firstGrandFather, secondGrandFather, thirdGrandFather dynamically. Also I don't know what their children props I need to define would be in the object. Some may have spouse,age,work props inside some may not also I don't know how many of these I would get. And these goes on for one or two more level.
In php it would be easy to create these in associative array easily but I am having hard time doing it in JS.
dynamic keys are possible in ES6+ Docs here
Basically, the syntax is:
obj[variable] = value;
Variable must contain a primitive value.
As for stacking, I'm afraid you have to get used to working with deep keys access with either dot or bracket notation. You can also assign a property of your object to a variable and then access its props.
So if obj is the object from your example:
const firstGrandfathersChildren = obj.firstGrandFather.children
It will have the following assigned:
{
first: 'AAA',
children: {
first: "AAAA"
}
}

How to update the value of a single property within a state object in React.js?

So I have the following object structure:
const SamplePalette = {
id: 1,
name: "Sample Palette",
description: "this is a short description",
swatches: [
{
val: "#FF6245",
tints: ["#FFE0DB", "#FFA797"],
shades: ["#751408", "#C33F27"]
},
{
val: "#FFFDA4",
tints: ["#FFFFE1"],
shades: ["#CCCB83"]
},
{
val: "#BFE8A3",
tints: ["#E7FFD7"],
shades: ["#95B77E"]
}
]
}
Let's imagine that this object is managed by the state of my app like this:
this.state = {
currentPalette: SamplePalette,
}
My question is how would I go about updating the val property of a given swatch object in the swatches array? Or more generally - how do I only update pieces of this object?
I tried using the update helper as well as to figure out how Object.assign() works, however I've been unsuccessful and frankly can't really grasp the syntax by just looking at examples.
Also, since I'm going to be modifying this object quite a lot, should I look into maybe using Redux?
[EDIT]
I tried #maxim.sh suggestion but with no success:
this.setState(
{ currentPalette: {...this.state.currentPalette,
swatches[0].val: newValue}
})
Consider you have new new_swatches
I think the clearer way is to get array, update it and put back as:
let new_swatches = this.state.currentPalette.swatches;
new_swatches[0].val = newValue;
this.setState(
{ currentPalette:
{ ...this.state.currentPalette, swatches: new_swatches }
});
Also you have : Immutability Helpers or https://github.com/kolodny/immutability-helper
Available Commands
{$push: array} push() all the items in array on the target.
{$unshift: array} unshift() all the items in array on the target.
{$splice: array of arrays} for each item in arrays call splice() on the target with the parameters provided by the item.
{$set: any} replace the target entirely.
{$merge: object} merge the keys of object with the target.
{$apply: function} passes in the current value to the function and updates it with the new returned value.

Using objects to store a list of names

I was wondering how to use an object to store a list of different names and access them by simply using the key.
Do I have to use embedded object like this.
var f =
{
0 : { name : "John" },
1 : { name : "Phillip" }
};
console.log(f[1].name);
Do not over-complicate things. Why don't you just try a simple array?
var f = [
{ name : "John" },
{ name : "Phillip" }
];
console.log(f[1].name);
Why not just an array, which is indexed identically? Do you actually need a name: attribute for some reason?
var names = [ 'John', 'Phillip' ];
Instead of names[0].name, which is pretty redundant, you'd just use names[0]...
He wants to access them by key:
var people = {
John:{ age:33},
Bob :{ age:42}
};
Now you can truly access them by key:
console.log(people["John"].age);
or this way (although odd):
console.log(people.John.age);
No looping is necessary, you are using the power of javascripts associative syntax to index directly into your data structure. No need to refer to some arbitrary integer index either.
This definitely works but typically you'd use a more appropriate property to index than just a name like perhaps an employee id.
You can use like this
Var names = [
{ 'name' : 'ashwin', age: 18 },
{'name' : 'jhon', 'age' : 20 }
];
console.log ( names[0].name );

Categories

Resources