Related
This question already has answers here:
How to map more than one property from an array of objects [duplicate]
(7 answers)
Closed last year.
I need to find first child element in array and just return it.
Here is problem because here is few children elements and i need loop thought each and return every first children element.
Example of array:
let allItems =
[{ id: 1 ,
name: 'Test 1' ,
children: [
id: 12,
title: 'Child element'
]
},
{
id: 2 ,
name: 'Test 2'
},
{
id: 3 ,
name: 'Test 3',
children: [
id: 12,
title: 'Child element',
children: [
id: 123,
title: 'GRAND Child element',
]
]
}]
What's the problem here? Since there can be many children elements, do I need to find a parent for each of those elements?
After looping i need array to be:
[{ id: 1 ,
name: 'Test 1'
},
{
id: 2 ,
name: 'Test 2'
},
{
id: 3 ,
name: 'Test 3'
}]
Wihout children elements.
What I am try:
allItems.map(item => item).filter(filteredItem => !filteredItem.children);
But this is no return me good results
Based on your expected output, here is my solution.
Also note, that you had missing curly braces with your children.
See you modified snippet below:
let allItems = [{
id: 1,
name: 'Test 1',
children: [{
id: 12,
title: 'Child element'
}]
},
{
id: 2,
name: 'Test 2'
},
{
id: 3,
name: 'Test 3',
children: [{
id: 12,
title: 'Child element',
children: [{
id: 123,
title: 'GRAND Child element',
}]
}]
}
]
console.log(allItems.map(item => {
return {
id: item.id,
name: item.name
}
}))
Using map and destructuring is a nice way to achieve what you're looking for
let allItems = [{
id: 1,
name: 'Test 1',
children: [{
id: 12,
title: 'Child element'
}]
},
{
id: 2,
name: 'Test 2'
},
{
id: 3,
name: 'Test 3',
children: [{
id: 12,
title: 'Child element',
children: [{
id: 123,
title: 'GRAND Child element',
}]
}]
}
];
const res = allItems.map(x => {
const {id, name} = x;
return {id, name};
});
console.log(res);
Use these propertys for call first child:
.firstchild==>this property calls first Node
.firstElementChild==>calls first element
I have data as Array of Array in my content.js component which should serve my parent component Catalogues.js to display the data passed as props to child component Groups.js.
content.js file is:
const content = [
[
{
id: 1,
category: 'Hymns',
track1:
[
{
title: 'Song 1',
text: 'When peace like a river attendeth my way',
},
],
track2:
[
{
title: 'Song 2',
text: 'It is well with my soul',
},
],
track3:
[
{
title: 'Song 3',
text: 'Praise the Lord, praise the Lord',
},
],
},
],
[
{
id: 2,
category: 'Rock',
track1:
[
{
title: 'Song 1',
text: 'Open the eyes of my heart',
},
],
track2:
[
{
title: 'Song 2',
text: 'Here is our god',
},
],
track3:
[
{
title: 'Song 3',
text: 'Becaue he lives',
},
],
},
],
[
{
id: 3,
category: 'High Life',
track1:
[
{
title: 'Song 1',
text: 'I will bless thye lord at all times',
},
],
track2:
[
{
title: 'Song 2',
text: 'Who is like unto thee',
},
],
track3:
[
{
title: 'Song 3',
text: 'Blesed be the name of the Lord',
},
],
},
],
];
export default content;
The child Group.js component is:
import React from 'react';
import { FaLevelDownAlt } from 'react-icons/fa';
import './groups.css';
const Groups = ({ item: { category, track1, track2, track3 } }) => (
<div className="groups-container">
<div className="category">
<p className="categoryArrows">
<FaLevelDownAlt color="#2b74b7" size={35} />
</p>
<p className="categoryTitle">{category}</p>
</div>
<div className="alltracks">
<div className="track">
<h1>{track1.title}</h1>
<p>{track1.text}</p>
</div>
<div className="tracks">
<h1>{track2.title}</h1>
<p>{track2.text}</p>
</div>
<div className="track">
<h1>{track3.title}</h1>
<p>{track3.text}</p>
</div>
</div>
</div>
);
export default Groups;
And the parent component Catalogues.js is:
import React, { useEffect } from 'react';
import Groups from '../../components/Groups';
import content from './content';
const Catalogues = () => (
<div className="catalogues-section">
<div className="catalogues-heading">
<h1 className="catalogues-text">Songs in the service</h1>
</div>
<div className="catalogues-container">
{content.map((item, index) => (
<Groups key={index} item={item} />
))}
</div>
</div>
);
export default Catalogues;
The problem is that the browser keeps showing “Cannot read property 'category' of undefined”. I have tried many possibilities found on internet but not to avail. Sometimes it says “Cannot read property 'title' of undefined”, but I’m used with passing props in React. I fail to understand what is going on in this case. Can somebody tell me how to solve this issue? I’ll really appreciate.
Your content is probably not in the format that you want it to be -- you're using a bunch of unnecessary [] which are creating extra arrays where you don't need them. If you change your content to the following, your code should work:
const content = [
{
id: 1,
category: 'Hymns',
track1:
{
title: 'Song 1',
text: 'When peace like a river attendeth my way',
},
track2:
{
title: 'Song 2',
text: 'It is well with my soul',
},
track3:
{
title: 'Song 3',
text: 'Praise the Lord, praise the Lord',
},
},
{
id: 2,
category: 'Rock',
track1:
{
title: 'Song 1',
text: 'Open the eyes of my heart',
},
track2:
{
title: 'Song 2',
text: 'Here is our god',
},
track3:
{
title: 'Song 3',
text: 'Becaue he lives',
},
},
{
id: 3,
category: 'High Life',
track1:
{
title: 'Song 1',
text: 'I will bless thye lord at all times',
},
track2:
{
title: 'Song 2',
text: 'Who is like unto thee',
},
track3:
{
title: 'Song 3',
text: 'Blesed be the name of the Lord',
},
},
];
Note how now, for example, each track1 is just an object ({}) and not an array of objects ([{}]).
I reproduced your codes and got the items displayed properly. Every time you face "undefined" you need to console log the content and see whether or not it is found by parent component. Your content format is not relevant for the map() function to map through it since it will map through array of object, just like #jnpdx mentioned earlier. So take advantage on his format and do document.write(content) to see whether you get [object object]. If you get that then you can continue with this answer. Otherwise your import of 'content' may be also wrong.
this is the right content format:
const content = [
{
id: 1,
category: 'Hymns',
track1:
{
title: 'Song 1',
text: 'When peace like a river attendeth my way',
},
track2:
{
title: 'Song 2',
text: 'It is well with my soul',
},
track3:
{
title: 'Song 3',
text: 'Praise the Lord, praise the Lord',
},
},
{
id: 2,
category: 'Rock',
track1:
{
title: 'Song 1',
text: 'Open the eyes of my heart',
},
track2:
{
title: 'Song 2',
text: 'Here is our god',
},
track3:
{
title: 'Song 3',
text: 'Because he lives',
},
},
{
id: 3,
category: 'High Life',
track1:
{
title: 'Song 1',
text: 'I will bless the lord at all times',
},
track2:
{
title: 'Song 2',
text: 'Who is like unto thee',
},
track3:
{
title: 'Song 3',
text: 'Blessed be the name of the Lord',
},
},
];
Then assuming that you get [object object] by document.write(content), in the Catalogues.js change yours by this:
import React, { useEffect } from 'react';
import Groups from '../../components/Groups';
import content from './content';
const Catalogues = () => (
<div className="catalogues-section">
<div className="catalogues-heading">
<h1 className="catalogues-text">Songs in the service</h1>
</div>
<div className="catalogues-container">
{content.map((item, index) => (
<Groups key={index} category={item.category} title1={item.track1.title} text1={item.track1.text} title2={item.track2.title} text2={item.track2.text} title3={item.track3.title} text3={item.track3.text}/>
))}
</div>
</div>
);
export default Catalogues;
Because you have nested objects inside your objects.
Then change your Groups.js by:
import React from 'react';
import { FaLevelDownAlt } from 'react-icons/fa';
import './groups.css';
const Groups = ({ category, title1, text1, title2, text2, title3, text3 }) => (
<div className="groups-container">
<div className="category">
<p className="categoryArrows">
<FaLevelDownAlt color="#2b74b7" size={35} />
</p>
<p className="categoryTitle">{category}</p>
</div>
<div className="alltracks">
<div className="track">
<h1>{title1}</h1>
<p>{text1}</p>
</div>
<div className="tracks">
<h1>{title2}</h1>
<p>{text2}</p>
</div>
<div className="track">
<h1>{title3}</h1>
<p>{text3}</p>
</div>
</div>
</div>
);
It's more about iteration sake. Because doing what you did like
<Groups key={index} item={item} /> and
const Groups = ({ item: { category, track1, track2, track3 } }) => (...)
I gets the 'category' props, but it didn't map through the tracks nested object to pick 'title' and 'text' for each.
first you need convert string to array
just do JSON.parse( your props)
I want to delete the 1 ids of cardItems of my list with 0 ids and keep the order of the lists. what is the best way?
lists: [
{
id: '0',
title: 'LIST 1',
cardItems: [
{
id: '0',
text: 'Card 1',
},
{
id: '1',
text: 'Card 2',
},
{
id: '2',
text: 'Card 3',
},
],
},
]
You can use .find to get the list item by id, and then remove the card item using .filter:
const lists = [
{
id: '0',
title: 'LIST 1',
cardItems: [
{ id: '0', text: 'Card 1' },
{ id: '1', text: 'Card 2' },
{ id: '2', text: 'Card 3' },
],
},
];
const removeCardItem = (list, listItemId, cardItemId) => {
const arr = [...list];
// get list item by id
const item = arr.find(listItem => listItem.id === listItemId);
// remove card item by id if found
if(item)
item.cardItems = item.cardItems.filter(cardItem =>
cardItem.id !== cardItemId
);
return arr;
}
console.log( removeCardItem(lists, '0', '1') );
Something similar to
if(lists[0].cardItems[0].id === 1){
lists[0].cardItems.splice(0,1);
}
Obviously this will only check that one value, but this can easily be implemented into a loop or nested loops or whatever you need. (I can't know since I can't see all of your code)
Your question is a little bit hard to understand, but this was my best guess at helping you out! If this wasn't the answer you're looking for then please give us more information so we can help you more effectively!
I am experimenting with React and the react-data-table-component. I have set up a test table like this:
<DataTable
title={'TestTitle'}
columns={[{ name: 'test 1', selector: 'test1' }, { name: 'test 2', selector: 'test2' }, { name: 'test 3', selector: 'test3' }, { name: 'test 4', selector: 'test4' }, { name: 'test 5', selector: 'test5' }]}
striped
responsive
pagination paginationRowsPerPageOptions={[5, 10, 25, 50, 100]} />
I noticed that there is a div generated to the right of the to the title div in the table. It only has some weird classes assigned to it.Is it possible enter data in this div with some property to the DataTable?
I have experimented with the subHeader properties but it puts the new text under he title, making the table slightly higher which is not desirable.
<DataTable
title={'TestTitle'}
subHeader subHeaderComponent={'TestSubHeader'}
columns={[{ name: 'test 1', selector: 'test1' }, { name: 'test 2', selector: 'test2' }, { name: 'test 3', selector: 'test3' }, { name: 'test 4', selector: 'test4' }, { name: 'test 5', selector: 'test5' }]}
striped
responsive
pagination paginationRowsPerPageOptions={[5, 10, 25, 50, 100]} />
Ok, so apparently I am a little bit too impatient for my own good. About one minute after I posted this question I realised that the actions property does exactly the thing I wanted. I guess that I probably should delete this question now. Or is this information usable for others?
Response format:
const fakeDatabase = {
quizzes: [{
id: v4(),
title: 'Get started',
text: 'hey',
completed: true,
hints: [{
id: 1,
text: 'Hint 1'
}, {
id: 2,
text: 'Hint 2'
}]
}, {
id: v4(),
title: 'What are you waiting for?',
text: 'ho',
completed: true,
hints: [{
id: 3,
text: 'Hint 3'
}, {
id: 4,
text: 'Hint 4'
}]
}, {
id: v4(),
title: 'Remember! create more than you consume',
text: 'let’s go',
completed: false,
hints: [{
id: 5,
text: 'Hint 5'
}, {
id: 6,
text: 'Hint 6'
}]
}],
};
I have the following schema:
import { Schema, arrayOf } from 'normalizr';
export const hint = new Schema('hints');
export const quiz = new Schema('quizzes', {
hints: [ hint ]
});
export const arrayOfQuiz = arrayOf(quiz);
But after normalizing I get the following response:
normalize(response, schema.arrayOfQuiz)
So, basically my quiz is normalized properly but hints is kept as it is, I don't know if I am missing something.
It looks like you're using normalizr v2.x. Only in v3.0.0 was plain array syntaxt [ hint ] added. In v2.x, you need to use arrayOf(hint).