How to insert map data to an array of object - reactjs

I am mapping out item values which is an array
const mappedItems = items.map(item => {
return (
<div key={item.id}>
<h2>{item.name}</h2>
<h2>{item.quantity}</h2>
</div>
)
});
What get outputted is like this:
Fun Mix
1
Potato Chips
5
I am trying to insert the items to my DB from my API, and the structure of the fields is like this:
Items: {
name: //Since the mapped value of the name is an array how can I store all the mapped names in this name field which is an object
quantity: //Same for quantity
},
In my backend controller, I am getting the value like this:
const order = new Order({
Items: req.body.Items,
});
My DB structure where the items are being inserted to is like this
Items: [
{
name: { type: String, required: true },
quantity: { type: Number, default: },
}
]

You could do like this (unless I missunderstood what you are trying to do):
const backendItems = items.map(item => {name:item.name, quantity: item.quantity})
So in the end, backendItems looks like this with your example:
backendItems: [
{
name: "Fun mix",
quantity: 1,
},
{
name: "Potato Chips",
quantity: 5,
}
]

Related

How to fetch array objects from api using axios?

Im fetching data from api using axios.
I have array of objects.
I would like to fetch objects inside array.
Here is api : https://51fgc922b7.execute-api.ap-south-1.amazonaws.com/dev/productpreview?product_id=122003
enter image description here
Here is what i tried !
useEffect(() => {
if (props.product_id) {
axios.
get(`https://51fgc922b7.execute-api.ap-south-1.amazonaws.com/dev/productpreview?product_id=${props.product_id}`)
.then((res) => {
console.log(res.data)
setModelData(res.data.data[0])
})
.catch((error) => {
setIsErrorImage(true)
})
}
}, []);
Im able to fetch data but what im trying to achive is that, there are three objects with camera objects called 0,1,2 and i want to fetch them.
I'm not sure about your requirement but as far as I understood you just want the array of objects from the data you get. You can get that simply by traversing the object like
const cameraData = res.data.reduce((acc,el) => [...acc, ...el.camera], [] )
console.log(res.data) if correct ,
setModelData(res.data)
and in return example ;
modelData.map((item)=> {
return (
<div> {item.camera.map((data)=>{
return (
<div> {data.camera_beta} </div>
)
})}
</div> )})
this is what i want to tell
const [modelData, setModelData] = useState([
{
name: 'Electronics',
slug: 'electronics',
count: 11,
items: [
{ name: 'Phones', slug: 'phones', count: 4 },
{ name: 'Tablets', slug: 'tablets', count: 5 },
{ name: 'Laptops', slug: 'laptops', count: 2 },
],
},
{
name: 'Clothing',
slug: 'clothing',
count: 12,
items: [
{ name: 'Tops', slug: 'tops', count: 3 },
{ name: 'Shorts', slug: 'shorts', count: 4 },
{ name: 'Shoes', slug: 'shoes', count: 5 },
],
}
])
you have data like this.
this way you set the data into setmodeldata in useeffect.
in useffect after set
console.log(modelData) and
console.log(modelData[0])
you can see the difference between the two.one comes in the form of an object and the other as an array.
at most you can map them

ant design table with dynamic children columns

I'm using ant's table and trying to setup dynamic columns.
What I need is a table that shows a list of users with their performance for each of the classes as in the example below.
Details: I have a grouped column Performance that can have different sub-columns (current example shows columns science and physics). I'm calling renderContent() which sets up an object that has property children. I found this "solution" from ant's example here. The problem is that ant's example outputs children prop type string, while my function outputs prop type array. Which results in the error.
Here is a link to sandbox:
https://codesandbox.io/embed/ecstatic-cookies-4nvci?fontsize=14
Note: if you uncomment children array in columns [line 46-59], you will see what my expected result should be.
The render method shouldn't return the object with children array. To use the render method, you would have to return a valid React component (or simply HTML tag ---like span).
However in your case, I prefer we extract subjects before passing it into the table and then generate children array dynamically. Something like below:
const renderContent = (value, row, index) => {
return setupPerformance(value)
};
const setupPerformance = performance => {
return performance.map(p => {
const { id, title, percentage } = p;
return <span>{percentage}%</span>
});
};
const data = [
{
key: 0,
firstName: "John",
lastName: "Smith",
performance: [
{
id: 1,
title: "science",
percentage: 75
},
{
id: 2,
title: "physics",
percentage: 36
}
]
},
{
key: 1,
firstName: "Ann",
lastName: "Smith",
performance: [
{
id: 1,
title: "science",
percentage: 68,
timeSpent: 50,
completionDate: "2019-02-07"
},
{
id: 2,
title: "physics",
percentage: 100
}
]
}
];
let subjects = data[0].performance
const columns = [
{
title: "Full Name",
children: [
{
title: "firstName",
dataIndex: "firstName",
key: "firstName"
},
{
title: "lastName",
dataIndex: "lastName",
key: "lastName"
}
]
},
{
title: "Performance",
dataIndex: "performance",
children:
subjects.map(e => {
return {
title: e.title,
dataIndex: "performance["+(e.id-1)+"].percentage",
key: "key-"+e.id,
render: value => <span>{value}%</span>
}
})
}
];
Because of the solution in answer from Mobeen does not work anymore, I have tried to solve this.
I have extended the render method for the children columns of performance column:
...
{
title: "Performance",
dataIndex: "performance",
children: subjects.map((assessment) => {
const { title, id } = assessment;
return {
title,
dataIndex: "performance",
key: id,
render: (values) =>
values.map((value, index) => {
let ret;
if (index === id - 1) ret = values[index].percentage + "%";
return ret;
})
};
})
}
...
It returns only the percentage value of the subject with the corresponding id.
It is not very clean, but it works.
Check the solution in sandbox: https://codesandbox.io/s/prod-lake-7n6zgj

Add object to existing array in state

I have an application that uers lets create new tables, lets say I have the following state:
const initialState = {
table: [{
id: 1,
item: {}
}]
}
Now I want to add new objects to the item:
The reducer:
case types.ADD_ITEM:
return {
...state,
table: [...state.table, { item: action.item}],
loading: false
}
So after user adds new items in a table the state should look something like this:
table: [
// table with id 1
{
id: 1,
item: {
id: '1',
data: 'etc'
}
item: {
id: '2',
data: 'blabla'
}
},
// table with id 2
{
id: 2,
item: {
id: '1'
data: 'etc'
}
},
// etc
]
I think I have my reducer wrongly setup.. the tables are added correctly, but Items not.
Current format is:
table: [
{
id: 1,
item: []
},
{
item: {
id: '1'
}
}
]
I think you are trying to add the contents of action.item to your array. What you're currently doing is adding the contents as a new element. You can use the following to achieve your desired output:
case types.ADD_ITEM:
return {
...state,
table: [...state.table, { ...action.item }],
loading: false
}
Or if you want to get only the id field of the item, and store the item inside a item field:
case types.ADD_ITEM:
return {
...state,
table: [...state.table, { id: action.item.id, item: action.item }],
loading: false
}

React filter on item in array inside array

I am trying to return a filtered list in a mobx store but I cant figure out how the filter function properly works. I have a array that looks like this
#observable files = ([
{
id: '1',
fileType: 'Document',
files: [
{
name: 'test1',
size: '64kb',
date: '2018-01-19'
},
{
name: 'test2',
size: '94kb',
date: '2018-01-19'
}
]
},
{
id: '2',
fileType: 'List',
files: [
{
name: 'test3',
size: '64kb',
date: '2018-01-19'
},
{
name: 'test4',
size: '94kb',
date: '2018-01-19'
},
{
name: 'test5',
size: '94kb',
date: '2018-01-19'
}
]
} and so on...
I want to be able to filter on all names this.files[x].files[x].name
and then return the result. If I set the "What to put here" to this.files[0].files[0].name I am able to filter on the first entry of name. But how can i filter dynamically on all names?
#observable filter = ""
#computed get filteredFiles(){
var matchesFilter = new RegExp(this.filter, "i")
var filtered = this.files.filter(file => !this.filter || matchesFilter.test(What to put here?))
return filtered
}
Change matchesFilter.test(What to put here?) to
file.files.some(nestedfile=>matchesFilter.test(nestedFile.name))
if you want to also filter the inner list of files to only those that match then you need to .map the array
var filtered = this.files
.filter(file =>
!this.filter || file.files.some(nestedfile => matchesFilter.test(nestedFile.name)))
.map(file => ({ ...file,
files: file.files.filter(nesstedFile => matchesFilter.test(nestedFile.name))
}));

In a one to many relationship, is there a way to filter the parent objects via an attribute of the child?

I have a rails backend with the following relationships: a USER has many MOVES. a Move has many boxes. A Box has many items.
I have page that lists all of the boxes inside of a specific move and this page ALSO lists all of the items for that specific move. I have a search bar on this page that enables you to search for specific items. I am able to filter my items display, however, i cannot figure out how to filter my boxes BY the searching for the name of the items WITHIN them.
I have tried iterating over the array of Box objects, and then iterating over the key within each box that points to its array of items. I am able to get the filtered ITEMS, but I dont know how to translate that back to reflect the BOXES with those items.
For instance, in the console I tried:
var filteredBoxes = boxes.map((box) => {
return box.items.filter((i) => {
return i.name.includes(this.state.searchTerm)
})
})
But it keeps returning items, not the boxes im trying to filter.
This is how the JSON looks when I fetch my boxes. I used a serializer to list the items as well:
{
id: 1,
name: "Bedding",
category: "Bedroom",
move_id: 1,
move: {
id: 1,
name: "Leaving for College",
date: "2019-08-12",
user_id: 1
},
items: [
{
id: 1,
name: "Comforter",
image: "https://www.shopmarriott.com/images/products/v2/lrg/Marriott-down-duvet-comforter-MAR-112_1_lrg.jpg",
box_id: 1
},
{
id: 2,
name: "Throw Pillows",
image: "https://media.kohlsimg.com/is/image/kohls/3427815?wid=500&hei=500&op_sharpen=1",
box_id: 1
}
]
},
{
id: 2,
name: "Random Blankets",
category: "Den",
move_id: 1,
move: {
id: 1,
name: "Leaving for College",
date: "2019-08-12",
user_id: 1
},
items: [
{
id: 3,
name: "Pillows",
image: "https://www.greatsleep.com/on/demandware.static/-/Sites-tbp-master-catalog/default/dw9ff5c1cf/product-images/pillows/nautica/down-alt-pillow-2-pack-na-91644/nautica-down-alternative-pillow-2-pack_91644-icon-2500x2500.jpg",
box_id: 2
},
{
id: 4,
name: "Stuffed Animals",
image: "https://s7d9.scene7.com/is/image/JCPenney/DP0817201617082870M?resmode=sharp2&op_sharpen=1&wid=550&hei=550",
box_id: 2
}
]
},
{
id: 3,
name: "Cleaning Supplies",
category: "Kitchen",
move_id: 1,
move: {
id: 1,
name: "Leaving for College",
date: "2019-08-12",
user_id: 1
},
items: [
{
id: 5,
name: "Pillows",
image: "https://www.greatsleep.com/on/demandware.static/-/Sites-tbp-master-catalog/default/dw9ff5c1cf/product-images/pillows/nautica/down-alt-pillow-2-pack-na-91644/nautica-down-alternative-pillow-2-pack_91644-icon-2500x2500.jpg",
box_id: 3
},
{
id: 6,
name: "Stuffed Animals",
image: "https://s7d9.scene7.com/is/image/JCPenney/DP0817201617082870M?resmode=sharp2&op_sharpen=1&wid=550&hei=550",
box_id: 3
}
]
}
you just have to iterate boxes, and so filter items. Based on these filtered items you may choose to return or not a box to the list.
const data = [{
id:1,
name:"Bedding",
category:"Bedroom",
move_id:1,
move:{
id:1,
name:"Leaving for College",
date:"2019-08-12",
user_id:1
},
items:[
{
id:1,
name:"Comforter",
image:"https://www.shopmarriott.com/images/products/v2/lrg/Marriott-down-duvet-comforter-MAR-112_1_lrg.jpg",
box_id:1
},
{
id:2,
name:"Throw Pillows",
image:"https://media.kohlsimg.com/is/image/kohls/3427815?wid=500&hei=500&op_sharpen=1",
box_id:1
}
]
},
{
id:2,
name:"Random Blankets",
category:"Den",
move_id:1,
move:{
id:1,
name:"Leaving for College",
date:"2019-08-12",
user_id:1
},
items:[
{
id:3,
name:"Pillows",
image:"https://www.greatsleep.com/on/demandware.static/-/Sites-tbp-master-catalog/default/dw9ff5c1cf/product-images/pillows/nautica/down-alt-pillow-2-pack-na-91644/nautica-down-alternative-pillow-2-pack_91644-icon-2500x2500.jpg",
box_id:2
},
{
id:4,
name:"Stuffed Animals",
image:"https://s7d9.scene7.com/is/image/JCPenney/DP0817201617082870M?resmode=sharp2&op_sharpen=1&wid=550&hei=550",
box_id:2
}
]
},
{
id:3,
name:"Cleaning Supplies",
category:"Kitchen",
move_id:1,
move:{
id:1,
name:"Leaving for College",
date:"2019-08-12",
user_id:1
},
items:[
{
id:5,
name:"Pillows",
image:"https://www.greatsleep.com/on/demandware.static/-/Sites-tbp-master-catalog/default/dw9ff5c1cf/product-images/pillows/nautica/down-alt-pillow-2-pack-na-91644/nautica-down-alternative-pillow-2-pack_91644-icon-2500x2500.jpg",
box_id:3
},
{
id:6,
name:"Stuffed Animals",
image:"https://s7d9.scene7.com/is/image/JCPenney/DP0817201617082870M?resmode=sharp2&op_sharpen=1&wid=550&hei=550",
box_id:3
}
]
}];
const searchTerm = "Animals"
// function to filter sub-items
const filterItems = items => items.filter((i) => searchTerm ? i.name.includes(searchTerm) : i.name);
const filteredBoxes = data.map(boxes => {
//filter sub-items
const items = filterItems(boxes.items);
//in case there is any item, return that boxes
if (items.length) {
return Object.assign({}, boxes, { items })
}
// in case there is nothing, return false
return false;
}).filter(Boolean); // filter the boxes list removing the false values
console.log('filteredBoxes', filteredBoxes);

Resources