JavaScript Object Manipulation Questions - javascript

At the moment I am working on an ionic app (angular1) and I am working on a huge object.
The Object will look like this:
userWorkouts: [
{
title: '3 Split',
id: 1,
workoutImg: '',
workoutSessions: {
1: {
workoutSessionName: 'Monday',
workoutExerciseList: {
1: {
exerciseName: "Pull Ups",
exerciseSets: {
1: 20,
2: 12,
3: 8
}
},
2: {
exerciseName: "Pull Ups",
exerciseSets: {
1: 20,
2: 12,
3: 8
}
}
}
}
}
},
{
title: 'Kraftausdauer Teil 1',
id: 2,
workoutImg: ''
},
{
title: 'Kraftausdauer Teil 2',
id: 3,
workoutImg: ''
},
{
title: '7 Minuten Training',
id: 4,
workoutImg: ''
},
{
title: 'Workout Zuhause',
id: 5,
workoutImg: ''
}
]
For Example: A User have x Workouts. Each Workout have x Sessions (Monday, Wednesday, Friday). A session have also x Exercises with x sets.
The Problem: I want to modify this object and I have a few problems:
Problem: I want to add Sessions (Monday, Wednesday, Friday).
var session = {
workoutSessionName: sessionName
};
userWorkouts[1].push(session)
Doesn't work, because its an object. Is there another way to "push" to an object?

if i understood try to change to this.
userWorkouts: [
{
title: '3 Split',
id: 1,
workoutImg: '',
workoutSessions: [{
{
workoutSessionName: 'Monday',
workoutExerciseList: [{
1: {
exerciseName: "Pull Ups",
exerciseSets: {
1: 20,
2: 12,
3: 8
}
},
2: {
exerciseName: "Pull Ups",
exerciseSets: {
1: 20,
2: 12,
3: 8
}
}
}
}
]
}
},
{
title: 'Kraftausdauer Teil 1',
id: 2,
workoutImg: ''
},
{
title: 'Kraftausdauer Teil 2',
id: 3,
workoutImg: ''
},
{
title: '7 Minuten Training',
id: 4,
workoutImg: ''
},
{
title: 'Workout Zuhause',
id: 5,
workoutImg: ''
}
]
and use like this
var session = {
workoutSessionName: sessionName
};
userWorkouts[1].workoutSessions.push(session)

Not sure you need to use 1. array or 2. object for workoutSessions
You could use array to hold workoutSessions instead of object because you are already using an integer as a key and then just add using push()
Check angular.extend https://docs.angularjs.org/api/ng/function/angular.extend
Here is a plunk for option 2:
https://plnkr.co/edit/x0isJdzXHq2gX7vfsQdG?p=preview

Related

how to add nested object with new object [duplicate]

This question already has answers here:
Add new element to an existing object
(6 answers)
Closed 3 years ago.
Actually, I want to add hats object to clothing object, i don't want to change object to array of object.
Can anyone help me how to add hats in my scenario.
const clothing = {
shirts:{
id: 1,
title: 'shirts' ,
item: [
{
id: 01,
name:'plain shirt',
},
{
id: 02,
name: 'stripe shirt',
},
],
},
tshirt: {
id: 2,
title: 't-shirt',
item: [
{
id: 03,
name: 'plain t-shirt',
},
{
id: 04,
name: 'stripe t-shirt',
}
],
},
}
const newClothing = {...clothing};
newClothing[{hats:{id:3, title:'hats', item:[{id:05, name:'blue hats'}]}}];
console.log(newClothing.hats);
This is the simplest way you can do it:
const newClothing = {...clothing, hats: { ...your hats object here } };
From what I understand, I don't think you need to do anything fancy here. Simply add a property as follows:
clothing.hats = {
id:3,
title:'hats',
item:[{id:05, name:'blue hats'}]
}
Use . notation to add the hats object
const clothing = {
shirts:{
id: 1,
title: 'shirts' ,
item: [
{
id: 01,
name:'plain shirt',
},
{
id: 02,
name: 'stripe shirt',
},
],
},
tshirt: {
id: 2,
title: 't-shirt',
item: [
{
id: 03,
name: 'plain t-shirt',
},
{
id: 04,
name: 'stripe t-shirt',
}
],
},
}
clothing.hats={id:3, title:'hats', item:[{id:05, name:'blue hats'}]};
console.log(clothing.hats);

How to Assign Values from one JSON Object List from Another JSON Object List

I have two JSON objects: I need to substitute the values from the properties from the product JSON with values from the properties from the branch JSON.
This is about plain JavaScript.
I have tried it with map and filter but the problem is that when there is no brand for a certain product the application crashes and that should be prevented. I also tried it with map and if's see JSFiddle link below.
var product = {
products: [{
ID: 1,
brandDescr: 'substitute', //this value should be substituded with the branch Description
brandID: 1,
colorCode: 2,
colorDesc: 'substitute',
},
{
ID: 2,
brandDescr: 'substitute',
brandID: 2,
colorCode: 3,
colorDesc: 'substitute',
},
{
ID: 3,
brandDescr: 'substitute',
brandID: 12,
colorCode: 3,
colorDesc: 'substitute',
}
]
}
var brand = {
brands: [{
Description: 'BMW',
ID: 1
},
{
Description: 'Mercedes',
ID: 2
},
{
Description: 'Audi',
ID: 3
},
]
}
/**mthis method crashes when there is no Description for a Brand.
*for example for product ID 3 there is no brand description because brandID
* 12 does not exist
*/
product.products.forEach((x) => {
x.brandDescr = brand.brands.filter(function (y) {
console.log('Value: ' + x.brandID + y.ID)
return x.brandID == y.ID
})[0].Description
});
So the result should be that the brandDescr in product should be substituted with the Description from brand and when there is no matching Description in brand the application should not crash.
And because performance is an issue, it should be prevented to do a double filter: the first time to check if the array is not empty, so to check if there is a branchDescr available for a product and the second time to do the actual substitution.
I have created a JSFiddle at
https://jsfiddle.net/Ben197/wpcz21e7/88/
var product = {
products: [{
ID: 1,
brandDescr: 'substitute', //this value should be substituded with the branch Description
brandID: 1,
colorCode: 2,
colorDesc: 'substitute',
},
{
ID: 2,
brandDescr: 'substitute',
brandID: 2,
colorCode: 3,
colorDesc: 'substitute',
},
{
ID: 3,
brandDescr: 'substitute',
brandID: 12,
colorCode: 3,
colorDesc: 'substitute',
}
]
}
var brand = {
brands: [{
Description: 'BMW',
ID: 1
},
{
Description: 'Mercedes',
ID: 2
},
{
Description: 'Audi',
ID: 3
},
]
}
product.products.forEach(productItem => {
const maybeBrand = brand.brands.find(i => i.ID === productItem.brandID);
if (maybeBrand) {
productItem.brandDescr = maybeBrand.Description;
}
});
console.log(product.products);
Instead of filter() you can use find() and instead of getting the first element (i.e.: ...[0].Description) you can use a different way to save the value:
product.products.forEach(function(ele, idx) {
var descr = brand.brands.find((currele) => currele.ID == ele.brandID);
// if descr is not undefined use descr.Description else use the default...
ele.brandDescr = descr && descr.Description || ele.brandDescr;
});
var product = {
products: [{
ID: 1,
brandDescr: 'substitute', //this value should be substituded with the branch Description
brandID: 1,
colorCode: 2,
colorDesc: 'substitute'
},
{
ID: 2,
brandDescr: 'substitute',
brandID: 2,
colorCode: 3,
colorDesc: 'substitute'
},
{
ID: 3,
brandDescr: 'substitute',
brandID: 12,
colorCode: 3,
colorDesc: 'substitute'
}
]
}
var brand = {
brands: [{
Description: 'BMW',
ID: 1
},
{
Description: 'Mercedes',
ID: 2
},
{
Description: 'Audi',
ID: 3
},
]
}
product.products.forEach(function(ele, idx) {
var descr = brand.brands.find((currele) => currele.ID == ele.brandID);
ele.brandDescr = descr && descr.Description || ele.brandDescr;
});
console.log(product);
Here is a simple snippet. This will work as you are wishing.
product.products.forEach((x) => {
brand.brands.map(e=>{
if(e.ID == x.brandID){
product.products[x.ID-1].brandDescr = e.Description;
}
})
});
console.log(product.products);

create nested json from plain jsons

I need to create a nested json object from a node-mysql results (json objects) here is what I'm trying to acomplish
Those are the mysql json objects that I have:
plants:
[{id: 1, name: 'plant 1'},
{id: 2, name: 'plant 2'}]
areas:
[{id: 1, nombre: 'area 1', plants_id: 1 },
{ id: 2, nombre: 'area 1 - plant 2', plantas_id: 2 },
{ id: 3, nombre: 'area n', plantas_id: 1 }]
machines:
[{id: 1, nombre: 'machine 1 - area 1', areas_id: 1 },
{ id: 2, nombre: 'machine 1 - area 2', areas_id: 2 },
{ id: 3, nombre: 'machine n', areas_id: 2 }]
And this the json that I need to create with the values of the previous json:
{
"plants":[
{
"name":"plant 1",
"areas": [
{ "name":"area 1",
"machines":[
{"nombre":"machine 1 - area 1"
}]
},
{ "nombre":"area 2",
"machines":[
{"nombre":"machine 1 - area 2"
}]
}
]
},
{
"name":"plant 2",
"areas": [
{ "nombre":"area 1 - plant 2",
"maquinas":[ ]
}
]
}
]
}
I've been trying with nested for loops but it's a mess, I read about linq but I have never worked with it
Sorry for the bad english. Any help is appreciated
Thanks and regards
This isn't an efficient solution but if your dataset is small, it works.
var plants = [
{ id: 1, name: 'plant 1' },
{ id: 2, name: 'plant 2' },
];
var areas = [
{ id: 1, nombre: 'area 1', plantas_id: 1 }, // there was a spelling mistake here
{ id: 2, nombre: 'area 1 - plant 2', plantas_id: 2 },
{ id: 3, nombre: 'area n', plantas_id: 1 },
];
var machines = [
{ id: 1, nombre: 'machine 1 - area 1', areas_id: 1 },
{ id: 2, nombre: 'machine 1 - area 2', areas_id: 2 },
{ id: 3, nombre: 'machine n', areas_id: 2 },
];
console.time('result');
function result() {
return plants.map(function(plant) {
return {
"name": plant.name,
"areas": areas.filter(function(area) {
return area.plantas_id == plant.id;
}).map(function(area) {
return {
"nombre": area.nombre,
"machines": machines.filter(function(machine) {
return machine.areas_id == area.id;
}).map(function(machine) {
return {
"nombre": machine.nombre,
};
}),
};
}),
};
});
}
console.timeEnd('result');
console.log(result());

How to filter normalized nested JSON data with no array?

after use normalizr library I have the following normalized JSON object result in the Redux state of my application:
{
sports: {
byId: {
1: {
id: 1,
name: 'Soccer',
slug: 'soccer'
},
2: {
id: 2,
name: 'Basketball',
slug: 'basketball'
},
3: {
id: 3,
name: 'American Football',
slug: 'american-football'
}
},
allIds: [
'1',
'2',
'3'
]
},
competitions: {
byId: {
'1': {
id: 1,
name: 'Competition 1',
short_name: 'Comp 1',
slug: 'comp-1',
sport: 1,
status: {
is_live: false
}
},
'2': {
id: 2,
name: 'Competition 2',
short_name: 'Comp 2',
slug: 'comp-2',
sport: 1,
status: {
is_live: true
}
},
'3': {
id: 3,
name: 'National Basketball League',
short_name: 'NBA',
slug: 'national-basketball-league',
sport_slug: 'basketball',
sport: 3,
status: {
is_live: true
}
}
},
allIds: [
'1',
'2',
'3'
]
}
What I want achieve: I want a list of competitions filtered/categorized by sports.
How can I do that?
Also I want to be able to group competitions by it's status.is_live.
So how can I get an list of competitions breakdown by sport that status.is_live equals true and competitions status.is_live equals false?
Any help is appreciated! Thanks
If you don't want to use lodash, you can write a .groupBy function pretty easily (example). You'll need to loop over the output object and reassign its children values with a for instead of using .mapValues.
I used lodash in the example, just to point out the logic.
Note: I'd remove the grouping in the data in the original response, and let the client do this on its own - it's easier to work on an unsorted array and filter/map that instead of working against values from an object that has redundant keys (since they represent groups by Id)
let data = {
sports: {
byId: {
1: {
id: 1,
name: 'Soccer',
slug: 'soccer'
},
2: {
id: 2,
name: 'Basketball',
slug: 'basketball'
},
3: {
id: 3,
name: 'American Football',
slug: 'american-football'
}
},
allIds: [
'1',
'2',
'3'
]
},
competitions: {
byId: {
'1': {
id: 1,
name: 'Competition 1',
short_name: 'Comp 1',
slug: 'comp-1',
sport: 1,
status: {
is_live: false
}
},
'2': {
id: 2,
name: 'Competition 2',
short_name: 'Comp 2',
slug: 'comp-2',
sport: 1,
status: {
is_live: true
}
},
'3': {
id: 3,
name: 'National Basketball League',
short_name: 'NBA',
slug: 'national-basketball-league',
sport_slug: 'basketball',
sport: 3,
status: {
is_live: true
}
}
},
allIds: [
'1',
'2',
'3'
]
}
}
let competitions = Object.values(data.competitions.byId)
// _.chain(arr) keeps returning `lodash` objects
// so I don't have to call it separately for every action
let filteredCompetitions = _.chain(competitions)
.groupBy(i => i.status.is_live)
.mapValues(i => _.groupBy(i, 'sport'))
.value() // returns the final value
console.log(filteredCompetitions)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Structuring Redux state by domain?

How should one structure Redux state when retrieving domain objects that have different search parameters.
In my application I display a list of organisations that the user filters, in a table. On the same page I will also display a smaller list of organisations that a user is part of, and perhaps in the future another small list on the same page that displays only organisations from another user.
Do i do this:
{
list_organisations: [
{ id: 1, name: 'foo1' //... },
{ id: 2, name: 'foo2' //... },
{ id: 3, name: 'foo3' //... },
{ id: 4, name: 'foo4' //... },
{ id: 5, name: 'foo5' //... },
],
user_one_organisations: [
{ id: 6, name: 'foo' //... },
{ id: 2, name: 'foo' //... },
],
user_two_organisations: [
{ id: 4, name: 'foo' //... },
{ id: 6, name: 'foo' //... },
],
}
or this:
{
users: [
{ id: 1, organisations: [7,3,8], name: 'billy' },
{ id: 2, organisations: [3,6,1], name: 'sam' },
]
organisations: [
{ id: 1, name: 'foo', //... },
{ id: 2, name: 'foo1', //... },
{ id: 3, name: 'foo2', //... },
{ id: 4, name: 'foo3', //... },
{ id: 5, name: 'foo4', //... },
{ id: 6, name: 'foo5', //... },
{ id: 7, name: 'foo6', //... },
{ id: 8, name: 'foo7', //... },
{ id: 9, name: 'foo8', //... },
],
}
If we go with option two, what do we do in the case that we need to lookup a single organisation for some purpose e.g. "check if a users email exists within an organisation" -- it all just seems so complex... especially when doing one off requests? should that even live in the redux state?
That would make it like so:
{
users: [
{ id: 1, organisations: [7,3,8], name: 'billy' },
{ id: 2, organisations: [3,6,1], name: 'sam' },
]
organisation_signup_form: {
doesUsersEmailExist: true / false / null,
}
organisations: [
{ id: 1, name: 'foo', //... },
{ id: 2, name: 'foo1', //... },
{ id: 3, name: 'foo2', //... },
{ id: 4, name: 'foo3', //... },
// ...
],
}
I'd actually recommend structuring your data in a completely different way. You want to make sure that all of your models are easy to get at so keeping them in an array can be tricky.
I'd suggest a state structure something like this:
users: {
1: { id: 1, organisations: [7,3,8], name: 'billy' },
2: { id: 2, organisations: [3,6,1], name: 'sam' },
},
userList: [1,2],
organisation_signup_form: {
doesUsersEmailExist: true / false / null,
},
organisations: {
1: { id: 1, name: 'foo', //... },
2: { id: 2, name: 'foo1', //... },
3: { id: 3, name: 'foo2', //... }
}
I got this advice from Dan on this question
check if a users email exists within an organisation
You don't have an email on the user model and it's not clear so it's quite difficult to answer that specific question.
One bit of advice I'd give is that you need to structure your state in a database kind of way but it doesn't have to be the same structure as your actual database or api endpoints.

Categories