It should be merged according to the category with the same product. If merged, the total price is calculated. I've tried nested v-for loops but it turn out wrong.
What is the best way to go about it?
The expected table structure-
The data-
[{
category: 'category_1',
product: '1',
price: 1000,
qty: 2,
},
{
category: 'category_1',
product: '1',
price: 1000,
qty: 1,
},
{
category: 'category_2',
product: '2',
price: 2000,
qty: 2,
},
{
category: 'category_1',
product: '3',
price: 3000,
qty: 1,
},
{
category: 'category_2',
product: '4',
price: 4000,
qty: 1,
},
{
category: 'category_1',
product: '5',
price: 5000,
qty: 1,
},
{
category: 'category_1',
product: '6',
price: 1000,
qty: 1,
},
];
Example Jsfiddle
https://jsfiddle.net/kw28tnm5/1/
NOTE-
The format of the data is okay to change.
Related
I'm making a budget tracker app. And I'm implementing the functions display and add transactions for the app. However, I'm struggling to find a way to dynamically set the image URL (the icon) based on the transaction category type.
The app is written in React Native.
For example, I have a list of transactions as below:
[
{
id: 1,
type: 'Expense',
category: 'Food',
description: 'Burger',
amount: 100,
date: '2020-10-10',
createdAt: '2021-01-01',
},
{
id: 2,
type: 'Expense',
category: 'Entertainment',
description: 'Movie',
amount: 200,
date: '2020-10-10',
createdAt: '2021-10-02',
},
{
id: 3,
type: 'Income',
category: 'Salary',
description: 'Salary',
amount: 1000,
date: '2020-10-10',
createdAt: '2021-10-03',
},
{
id: 4,
type: 'Expense',
category: 'Food',
description: 'Burger',
amount: 100,
date: '2020-10-10',
createdAt: '2021-01-01',
},
]
Then I want to display it in a list, and each list item contains the icon representing the category, like this image:
You can just import images and add them as a key like this :
import burgerImage from '../images/burger.jpg';
import movieImage from '../images/movie.jpg';
[
{
id: 1,
type: 'Expense',
category: 'Food',
description: 'Burger',
amount: 100,
date: '2020-10-10',
createdAt: '2021-01-01',
icon: burgerImage,
},
{
id: 2,
type: 'Expense',
category: 'Entertainment',
description: 'Movie',
amount: 200,
date: '2020-10-10',
createdAt: '2021-10-02',
icon: movieImage
},
]
Pass the icon key as a source to Image component like this :
data.map((datum)=> <Image source={datum.icon} />);
I think you should use category field to render icon be like:
const renderIcon = (icon) => {
switch (icon) {
case "Food":
return <Icon icon="food" />
case "Movie":
return <Icon icon="movie" />
// Diff case
default:
return <Icon icon="iconDefault" />
}
And in renderItem of FlatList:
const renderItem = ({ item, index }) => {
return (
// render wrapper
{renderIcon(item.category)}
// render name, time, price of product
)
}
I have an object that looks like this
category_1: [
[
id: 1,
name: 'Product 1',
tags: []
],
[
id: 2,
name: 'Product 2',
tags: []
]
],
category_2: [
[
id: 3,
name: 'Product 3',
tags: []
],
[
id: 4,
name: 'Product 4',
tags: ['blue']
],
[
id: 5,
name: 'Product 5',
tags: []
],
[
id: 6,
name: 'Product 6',
tags: ['blue']
]
]
and what I'm trying to do is grab everything in my category, for example category_2 and grab only the items that has blue in the tags.
This issue I'm having is that I get the first item and it just loops a couple of times with just that item.
Here is my code
getCategories(){
Object.keys(categories).forEach(category => {
if(category === 'category_2'){
categories[category].forEach(c => {
if(c.tags.includes('blue') === true){
this.categorydata.push(c)
}
});
}
})
}
First of all are you sure you want categories to be arrays of arrays? If you want items of categories to be objects instead of arrays than you are using the wrong notation. If you want your category to be consisted of objects and not arrays, change your code to this:
category_1: [
{ id: 1, name: "Product 1", tags: [] },
{ id: 2, name: "Product 2", tags: [] },
],
category_2: [
{ id: 3, name: "Product 3", tags: [] },
{ id: 4, name: "Product 4", tags: ["blue"] },
{ id: 5, name: "Product 5", tags: [] },
{ id: 6, name: "Product 6", tags: ["blue"] },
],
With that out of the way, you can do what you want using filter function.
Your code should look like this:
getCategories(categoryName, wantedTag){
return categories[categoryName].filter(item => item.tags.includes(wantedTag));
}
Tell a beginner web delepoer how to get all title from all objects in array
this is my array
0: {id: 6, category_id: 2, title: "Test", brand: "Test", serial_number: "2165412315864",…}
1: {id: 7, category_id: 3, title: "Test2", brand: "Test2", serial_number: "2165412315864",…}
2: {id: 8, category_id: 5, title: "New", brand: "New", serial_number: "2165412315864",…}
3: {id: 9, category_id: 1, title: "New2", brand: "New2", serial_number: "2165412315864",…}
Im try to use this code
categories: {
handler(categories) {
console.log('categories: ', categories[title]); //Debug
},
deep: true
}
If you want an array with just the titles you can use Array.map and pick the parts your interested in:
const arr = [{
id: 6,
category_id: 2,
title: "Test",
brand: "Test",
serial_number: "2165412315864"
},
{
id: 7,
category_id: 3,
title: "Test2",
brand: "Test2",
serial_number: "2165412315864"
},
{
id: 8,
category_id: 5,
title: "New",
brand: "New",
serial_number: "2165412315864"
},
{
id: 9,
category_id: 1,
title: "New2",
brand: "New2",
serial_number: "2165412315864"
}
];
const titles = arr.map(({ title }) => title);
console.log(titles);
The categories variable is actually an array here, so you can not use
categories['title']
// Or,
categories.title
here. To get all title property for each category inside the categories array you can use array .map() method like:
categories: {
handler(categories) {
const arr = categories.map(c => c.title)
console.log('titles: ', arr); //Debug
},
deep: true
}
I need to scroll my items horizontally but my data is divided to 4 rows every row contain 4 items. and I can scroll horizontally so the next 16 item come to the screen.
when using numColumns={4} it works if
horizontal={false}
but with
horizontal={true}
I can't specify numColumns attr.
Should I use SectionList instead of FlatList ?
and how it could be implemented ?
let items = [
{ id: 1, title: '1', price: '20' },
{ id: 2, title: '2', price: '16' },
{ id: 3, title: '3', price: '92' },
{ id: 4, title: '4', price: '93' },
{ id: 5, title: '5', price: '20' },
{ id: 6, title: '6', price: '16' },
{ id: 7, title: '7', price: '92' },
{ id: 8, title: '8', price: '93' },
{ id: 9, title: 'Grilled Steak', price: '20' },
{ id: 10, title: 'Pappas', price: '16' },
{ id: 11, title: 'Ciccione', price: '92' },
{ id: 12, title: 'Gyros Melt', price: '93' },
{ id: 13, title: 'Grilled Steak', price: '20' },
{ id: 14, title: 'Pappas', price: '16' },
{ id: 15, title: 'Ciccione', price: '92' },
{ id: 16, title: 'Gyros Melt', price: '93' },
];
<FlatList
keyExtractor={item => item.id}
data={items}
horizontal
numColumns={4}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>
I have the same issue with same scenario. making group data is quite a bad practice in case you have long array. so I play with styles of flatlist and I was successful. following is my code if you can take advantage out of it:
<ScrollView showsHorizontalScrollIndicator={false} horizontal={true} style={styles.flatListContainer}>
<FlatList
showsHorizontalScrollIndicator={false}
data={item.items}
numColumns={4}
renderItem={_showData}
columnWrapperStyle={styles.flatListColumnWraper}
keyExtractor={(item) => item.key}
style={styles.flatListDataContainer}
scrollEnabled={false}
contentContainerStyle={
styles.flatListContentContainerStyle
}
/>
</ScrollView>
flatListContainer: {
marginTop: height(2),
height:height(60),
paddingVertical:height(2)
},
flatListDataContainer: {
alignSelf: 'center',
},
flatListContentContainerStyle: {
alignSelf: 'center',
flexDirection: 'row',
justifyContent: 'space-evenly',
},
flatListColumnWraper:{
flexDirection: 'column',
},
Unfortunately FlatList doesn't support a number of columns when it is horizontal.
https://facebook.github.io/react-native/docs/flatlist#numcolumns
Multiple columns can only be rendered with horizontal={false} and will
zig-zag like a flexWrap layout. Items should all be the same height -
masonry layouts are not supported.
However, you could group your data so that for every cell in a horizontal FlatList 4 items are rendered.
let items = [
[ { id: 1, title: '1', price: '20' },
{ id: 2, title: '2', price: '16' },
{ id: 3, title: '3', price: '92' },
{ id: 4, title: '4', price: '93' } ],
[ { id: 5, title: '5', price: '20' },
{ id: 6, title: '6', price: '16' },
{ id: 7, title: '7', price: '92' },
{ id: 8, title: '8', price: '93' } ],
[ { id: 9, title: 'Grilled Steak', price: '20' },
{ id: 10, title: 'Pappas', price: '16' },
{ id: 11, title: 'Ciccione', price: '92' },
{ id: 12, title: 'Gyros Melt', price: '93' } ],
[ { id: 13, title: 'Grilled Steak', price: '20' },
{ id: 14, title: 'Pappas', price: '16' },
{ id: 15, title: 'Ciccione', price: '92' },
{ id: 16, title: 'Gyros Melt', price: '93' } ]
];
Then update your renderItem so that it handles the increased input, something like this.
renderItem = ({item}) => {
return item.map(i => <Text>{i.title}</Text>)
}
data: function(){
return {
items: [
{ id: '1', name: 'Item 1', bool: false},
{ id: '2', name: 'Item 2', bool: false},
{ id: '3', name: 'Item 3', bool: false},
{ id: '4', name: 'Item 4', bool: false}
],
checkedItems: [],
};
},
methods:
{
select: function(event, index) {
if (!this.items[index].bool) {
this.checkedItems.splice(index, 1);
} else {
this.checkedItems.push(this.items[index]);
}
}
}
When I click on the div it copies the items data into checkedItems and sets bool to true.
Is it possible to target the item id and remove that specific one from checkedItems as the current splice is removing the wrong item based off the index.
Why not use an object instead of an array, something like this:
data: function(){
return {
items: [
{ id: '1', name: 'Item 1', bool: false},
{ id: '2', name: 'Item 2', bool: false},
{ id: '3', name: 'Item 3', bool: false},
{ id: '4', name: 'Item 4', bool: false}
],
checkedItemsObj: {},
};
},
methods:
{
select: function(event, index) {
let item = this.items[index];
if (!item.bool) {
this.checkedItemsObj[item.id] = item
} else {
delete this.checkedItemsObj[item.id]
}
},
getCheckedItems: () => Object.values(data().checkedItemsObj)
}
Now to get the array of checked items anytime, you can call methods.getCheckedItems()