How do I update nested object by ID in VueJS - javascript

Issue:
I'm trying to update(axios.patch) active data from false to true of a nested object (children) by ID using axios patch request. I'm using vuejs as my frontend and json-server as my backend. Can anyone please help me.
Data:
{
"id": 3,
"icon": "store",
"name": "Store Management",
"children": [
{
"id": 1,
"name": "Tables",
"icon": "",
"active": false,
"path": "/store-management/tables"
},
{
"id": 2,
"name": "Discounts",
"icon": "",
"active": false,
"path": "/store-management/discounts"
},
{
"id": 3,
"name": "Surcharges",
"icon": "",
"active": false,
"path": "/store-management/surcharges"
},
{
"id": 4,
"name": "Promos",
"icon": "",
"active": false,
"path": "/store-management/promos"
}
],
"expanded": true,
"path": "",
"active": false,
"hasChildren": true
}
Function:
When I call the #click function the navigateChildren will execute and it needs to get the path of the nested object and at the same time update the active value to true or false.
async navigateChildren(id) {
try {
const menuChildren = await axios.get('http://localhost:3000/menu/3')
const menuChildrenList = menuChildren.data
const children = menuChildrenList.children[id - 1]
const inactive = await axios.patch(
'http://localhost:3000/menu/' + this.menuId,
{
active: false
}
)
console.log(inactive)
const active = await axios.patch('http://localhost:3000/menu/3', {
children: {
active: true
}
})
console.log(active)
const path = children.path
this.$store.commit('setMenuId', id)
this.$router.push(path)
console.log(children)
} catch (error) {
}
}
Many Thanks.

Related

How to update nested object property in array by id in javascript?

How can i updated isCompleted property to true on onClick. I can only access moduleContent id from route e.g.- "id": "cr1mod1content1". How can i update isCompleted property to true by only matching this id. Note: i'm using react/nextJS for this project.
here is my json data structure.
[
{
"id": 1,
"progress": 0,
"title": "Python Basics for Data Science",
"modules": [
{
"id": "cr1mod1",
"title": "Module 1- Python Basics",
"moduleContent": [
{
"type": "html",
"id": "cr1mod1content1",
"title": "Module Introduction and Learning Objectives",
"content": " <p> This module teaches the basics of Python and begins </p>",
"quizContent": [],
"isCompleted": false
},
{
"type": "video",
"id": "cr1mod1content2",
"title": "Video: Types (3:02)",
"content": "https://vimeo.com/23",
"quizContent": [],
"isCompleted": false
},
{
"type": "quiz",
"id": "cr1mod1content3",
"title": "Practice Quiz: Types",
"content": "",
"quizContent": [],
"isCompleted": false
}
]
},
{
"id": "cr1mod2",
"title": "Module 2 - Python Data Structures",
"moduleContent": [
{
"type": "html",
"id": "cr1mod2content1",
"title": "Module Introduction and Learning Objectives",
"content": " <p>This module begins a journey into Python data structure</p> ",
"quizContent": [],
"isCompleted": false
},
{
"type": "video",
"id": "cr1mod2content2",
"title": "Video: Types (8:31)",
"content": "https://vimeo.com/1",
"quizContent": [],
"isCompleted": false
},
{
"type": "quiz",
"id": "cr1mod2content3",
"title": "Practice Quiz: Types",
"content": "",
"quizContent": [],
"isCompleted": false
}
]
}
]
}
]
You can reach this in this way:
const arr = declare Your JSON array there
const id = 'cr1mod2content3'
for(const module of arr[0].modules) {
for(const item of module.moduleContent) {
if(item.id === id) item.isCompleted = true
}
}
Take into account that if your root JSON array may contain several elements, you will have to wrap the cycle with one more (root) iteration.
You can use some() of array for checking and update
const data = [
{
"id": 1,
"progress": 0,
"title": "Python Basics for Data Science",
"modules": [
{
"id": "cr1mod1",
"title": "Module 1- Python Basics",
"moduleContent": [
{
"type": "html",
"id": "cr1mod1content1",
"title": "Module Introduction and Learning Objectives",
"content": " <p> This module teaches the basics of Python and begins </p>",
"quizContent": [],
"isCompleted": false
},
{
"type": "video",
"id": "cr1mod1content2",
"title": "Video: Types (3:02)",
"content": "https://vimeo.com/23",
"quizContent": [],
"isCompleted": false
},
{
"type": "quiz",
"id": "cr1mod1content3",
"title": "Practice Quiz: Types",
"content": "",
"quizContent": [],
"isCompleted": false
}
]
},
{
"id": "cr1mod2",
"title": "Module 2 - Python Data Structures",
"moduleContent": [
{
"type": "html",
"id": "cr1mod2content1",
"title": "Module Introduction and Learning Objectives",
"content": " <p>This module begins a journey into Python data structure</p> ",
"quizContent": [],
"isCompleted": false
},
{
"type": "video",
"id": "cr1mod2content2",
"title": "Video: Types (8:31)",
"content": "https://vimeo.com/1",
"quizContent": [],
"isCompleted": false
},
{
"type": "quiz",
"id": "cr1mod2content3",
"title": "Practice Quiz: Types",
"content": "",
"quizContent": [],
"isCompleted": false
}
]
}
]
}
]
const updateData = (arr, idFilter) => {
arr.some(({modules}) => {
modules.some(({moduleContent}) => {
moduleContent.some(ele => {
if (ele.id === idFilter) {
return ele.isCompleted = true
}
return false
})
})
})
}
updateData(data, 'cr1mod1content1')
console.log(data)
You can use map double times to update
data[0].modules.map(item => item.moduleContent.map(obj => {
if (obj.id === "cr1mod1content1") {
obj.isCompleted = true
}
}));

How to filter Object from Object

I have 2 or more objects in Main Object.
How can I find one object againt this key value.
{
"0": {
"component": "AWAY",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": false,
"image": ""
},
},
"1": {
"component": "PHONE_BOTH",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": false,
"image": ""
}
},
"2": {
"component": "MEETING_ROOM",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": true,
"image": ""
}
}
}
I just want to get one object where inRoom = true
It is not recommended to index an object with numeric keys. Use an array instead then you can use filter directly on the array
const arr = [{
"component": "AWAY",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": false,
"image": ""
},
},
{
"component": "PHONE_BOTH",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": false,
"image": ""
}
},
{
"component": "MEETING_ROOM",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": true,
"image": ""
}
}
]
console.log(arr.filter(({currentUser}) => currentUser.inRoom === true))
You should convert your dictionary to an array and then find the object by a specific criteria using the find() array method. See implementation:
// usersDict is the given Main Object
// convert usersDict to array of user objects
let usersArray = Object.values(usersDict);
// find user which has inRoom flag true
let userInRoom = usersArray.find(o => !!o.currentUser.inRoom);
var bb = {
"0": {
"component": "AWAY",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": false,
"image": ""
},
},
"1": {
"component": "PHONE_BOTH",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": false,
"image": ""
}
},
"2": {
"component": "MEETING_ROOM",
"currentUser": {
"id": 1,
"userName": "abc",
"inRoom": true,
"image": ""
}
}
}
var kk = []
for (const man in bb) {
if(bb[man].currentUser.inRoom){
kk.push({man: bb[man]})
}
}
console.log(kk.length ? kk[0] : {})
First, you should convert your object to an array then use the filter method in the array:
// obj = your data
Object.values(obj).filter(obj => obj.currentUser.inRoom)

How to check any every array object property empty or not?

The purpose of function is to get false when all answers are empty. Currently, some how getting **false when only one single answers empty and rest have data inside.
what is the best way to check all answers are empty or not. It doesn't matter some has data and some doesn't. I just wanna see all empty or not.
const questions = [{
"answers": [{
"value": "Browns",
"selected": false,
},
{
"value": "Oranges",
"selected": false,
},
{
"value": "Purples",
"selected": false,
}
],
"info": "",
"type": "DESELECT",
"lastUpdated": "2021-11-01T22:50:28.359"
},
{
"answers": [],
"info": "",
"type": "DESELECT",
"lastUpdated": "2021-11-01T22:50:35.392"
},
{
"answers": [{
"value": "AnimalPrints",
"selected": false,
},
{
"value": "BigLogos",
"selected": true,
},
{
"value": "Floral",
"selected": false,
}
],
"info": "",
"type": "DESELECT",
"lastUpdated": "2021-11-01T22:50:43.883"
}
];
console.clear();
console.log("------------ES6------------");
const es6Result = questions.every((item) => !_.isEmpty(item.answers));
console.log(es6Result);
const lodashResult = _.every(questions, !_.isEmpty('answers'));
console.log("------------Lodash------------");
console.log(lodashResult);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>
You could use .some(), you will get true if at least 1 answers is not empty, and you will get false if all answers are empty
const es6Result = questions.some((item) => item.answers.length);
I think the logic you describe requires:
const lodashResult = !_.every(questions, _.isEmpty('answers'));
or
const es6Result = !questions.every((item) => _.isEmpty(item.answers));
const questions = [{
"answers": [{
"value": "Browns",
"selected": false,
},
{
"value": "Oranges",
"selected": false,
},
{
"value": "Purples",
"selected": false,
}
],
"info": "",
"type": "DESELECT",
"lastUpdated": "2021-11-01T22:50:28.359"
},
{
"answers": [],
"info": "",
"type": "DESELECT",
"lastUpdated": "2021-11-01T22:50:35.392"
},
{
"answers": [{
"value": "AnimalPrints",
"selected": false,
},
{
"value": "BigLogos",
"selected": true,
},
{
"value": "Floral",
"selected": false,
}
],
"info": "",
"type": "DESELECT",
"lastUpdated": "2021-11-01T22:50:43.883"
}
];
console.clear();
console.log("------------ES6------------");
const es6Result = questions.map((item) => _.isEmpty(item.answers)).indexOf(true) > -1;
console.log(es6Result);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>
There's not really a need for lodash here. You should be able to accomplish what you want by using Array.prototype.every
questions.every((item) => item.answers.length > 0)
This will always return true, as long as all 'answers' array have one or more items inside, else false.
As Georgy said, you can use Array.prototype.some when you want to check for at least one of the items.

How do you render objects from json

I need to render some images from some json that I am being given. The code looks like
class App extends React.Component {
componentDidMount() {
$.get(
"url"
data => {
});
}
render() {
return React.createElement("div", null, "hello");
}}
ReactDOM.render(React.createElement(App, null), document.body);
"url" is the json that I have passed in (but I do not want to make it public). It looks similar to this:
{
"total_count": null,
"_links": {
"self": {
"href": ""
},
"next": {
"href": ""
}
},
"_embedded": {
"showorks": [{
"id": "",
"slug": "",
"created_at": "",
"updated_at": "",
"title": "",
"category": "",
"medium": ",
"date": "",
"dimensions": {
"in": {
"text": "",
"height": 70.9,
"width": 70.9,
"depth": null,
"diameter": null
},
"cm": {
"text": "180.1 × 180.1 cm",
"height": 180.1,
"width": 180.1,
"depth": null,
"diameter": null
}
},
"published": true,
"website": "",
"signature": "",
"series": null,
"prov": "",
"lit": "",
"hist": "",
"isst": "",
"additional_information": "",
"image_rights": "",
"blurb": "",
"unique": false,
"maker": null,
"icon": ,
"inquire": false,
"acquire": false,
"share": true,
"message": null,
"sell":,
"image_versions": ,
"_links": {
"thumbnail": {
"href": ""
},
"image": {
"href": "",
"templated": true
},
"partner": {
"href": ""
},
"self": {
"href": ""
},
"link": {
"href": ""
},
"genes": {
"href": ""
},
"rar": {
"href": ""
},
"cim": {
"href": ""
},
"coll": {
"href": ""
}
},
"_embedded": {
"editions": []
}
}, {
"id": "",
I need the thumbnail for each id but I'm not sure how to iterate through the json to pull out each thumbnail in react/javascript
First, I totally recommend you to use JSX syntax to use React better. To do that, you will need a few Javascript Array helper function and some methods.
As you can see below:
class App extends React.Component
{
componentDidMount()
{
// We could imagine the incoming JSON data
// const exampleJson =
// {
// elements:
// [
// { href: 'example1', text: 'link value', style: { height: '10px' } },
// ],
// };
// This fetch API will help you to get JSON from URL like JQuery $.get
const exampleJson = fetch('http://example.com/links.json')
.then(function(response)
{
return response.json(); // get the values of JSON as string type
})
.then(function(myJson)
{
return JSON.stringify(myJson); // convert the JSON data to javascript object
});
this.setState(exampleJson); // it's like this.setState({ elements: [array values] });
console.log(exampleJson); // to do debug of your JSON data
}
render()
{
// we getting the elements array from state object
// with object spread operator
const { elements } = this.state;
// get values all of your json array
// loop values to do React element
// return all new values to use loopAndSaveElements variable
const loopAndSaveElements = elements
.map(({ text, ...otherProps}) => React.createElement('a', otherItems, text));
// send return div of React as loopAndSaveElements as array children
return React.createElement("div", null, loopAndSaveElements);
}
}
By the way, i didn't run the snippet of example. But i hope it give you an information.
ES6+ Sources:
const
Array map
spread syntax
JSX syntax
fetch API

nested filter with lodash for parent children relationship

How to create a lodash to get the userID 10165381978 and its children userIDs for the following multi array ($scope.myVar)-
{
"children": [{
"userId": "1",
"name": "Kevin",
"type": "ROOT",
"active": true,
"children": [{
"userId": "10023872531",
"name": "Selvin",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10003200835",
"name": "adduser",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "-1111111",
"name": "Merisa",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10165381976",
"name": "Kam",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10165381977",
"name": "Pam",
"type": "USER",
"active": true,
"children": [{
"userId": "10165381978",
"name": "Ram",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10232392492",
"name": "Sam",
"type": "USER",
"active": true,
"children": []
}]
}]
}]
}]
}]
}
So from above I want to get-
10165381978, 10232392492
I tried-
var filterUser = function(userId){
lodash.filter($scope.myVar, function(o) { return o.userId})
}
And then called filterUser(10165381978);
But the result was empty object [].
Lodash does not provide a built-in utility to achieve this. You can solve this by recursively traversing throughout your nested collections. Check the solution below, each section of the code is commented.
function getIds(collection, ids) {
// store ids in this variable
var result = [];
// determines if an id is found,
var found = false;
// makes sure that ids is always an array of id
ids = [].concat(ids);
// iterate over the collection, name the callback for recursion
// if you prefer to use lodash, then use:
// _.each(collection, function iterator(value) {...});
collection.forEach(function iterator(value) {
// Matching the list of `ids` from the iterated userId.
// If a match is found, then we set `found` to true.
var isStop = ~ids.indexOf(value.userId) && (found = true);
// did we get a match?
if(found) {
// add the matched ID and the IDs from its descendants
result.push(value.userId);
}
// itereate recursively over its descendants
// If you prefer to use lodash then use:
// _.each(value.children, iterator)
(value.children || []).forEach(iterator);
// is the currently iterated item's ID within the list of `ids`?
if(isStop) {
// set `found` to false, to prevent adding IDs that aren't matched
found = false;
}
});
// return an array of IDs
return result;
}
var data = {
"children": [{
"userId": "1",
"name": "Kevin",
"type": "ROOT",
"active": true,
"children": [{
"userId": "10023872531",
"name": "Selvin",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10003200835",
"name": "adduser",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "-1111111",
"name": "Merisa",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10165381976",
"name": "Kam",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10165381977",
"name": "Pam",
"type": "USER",
"active": true,
"children": [{
"userId": "10165381978",
"name": "Ram",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10232392492",
"name": "Sam",
"type": "USER",
"active": true,
"children": []
}]
}]
}]
}]
}]
};
function getIds(collection, ids) {
// store ids in this variable
var result = [];
// determines if an id is found,
var found = false;
// makes sure that ids is always an array of id
ids = [].concat(ids);
// iterate over the collection, name the callback for recursion
// if you prefer to use lodash, then use:
// _.each(collection, function iterator(value) {...});
collection.forEach(function iterator(value) {
// Matching the list of `ids` from the iterated userId.
// If a match is found, then we set `found` to true.
var isStop = ~ids.indexOf(value.userId) && (found = true);
// did we get a match?
if(found) {
// add the matched ID and the IDs from its descendants
result.push(value.userId);
}
// itereate recursively over its descendants
// If you prefer to use lodash then use:
// _.each(value.children, iterator)
(value.children || []).forEach(iterator);
// is the currently iterated item's ID within the list of `ids`?
if(isStop) {
// set `found` to false, to prevent adding IDs that aren't matched
found = false;
}
});
// return an array of IDs
return result;
}
console.log('ID to find: 10165381978');
console.log(getIds(data.children, '10165381978'));
console.log('IDs to find: 10023872531, 10165381976');
console.log(getIds(data.children, [
'10023872531',
'10165381976'
]));
.as-console-wrapper {
min-height: 100%;
top: 0;
}

Categories