How to do in vue js three search fields with computed - javascript

I am trying to create three search fields. with an input and two selectors. somehow I managed to work with two but with three it is not working I need help
computed: {
filterMembers: function () {
let filtered = this.trabalinhos;
if (this.searchText) {
filtered = this.trabalinhos.filter(
(m) => m.title.toLowerCase().indexOf(this.searchText) > -1
);
}
if (this.searchTrabalho) {
filtered = filtered.filter(
(m) =>
m.title.toLowerCase().indexOf(this.searchTrabalho) ==
this.searchTrabalho.toLowerCase() > -1
);
}
if (this.select) {
filtered = filtered.filter(
(m) =>
m.title.toLowerCase().indexOf(this.select) ==
this.select.toLowerCase() > -1
);
}
return filtered;
},
},

Consider using includes.
computed: {
filterMembers() {
return this.trabalinhos
.filter(member => member.title.toLowerCase().includes(this.searchText))
.filter(member => member.title.toLowerCase().includes(this.searchTrabalho))
.filter(member => member.title.toLowerCase().includes(this.select))
}
}
OR
computed: {
filterMembers() {
return this.trabalinhos
.filter(member =>
member.title.toLowerCase().includes(this.searchText) &&
member.title.toLowerCase().includes(this.searchTrabalho) &&
member.title.toLowerCase().includes(this.select)
)
}
}

Related

ag-grid-react: getSortModel is not a function

I'm trying to get sort model from ag-grid-react component using getSortModel() but I'm getting getSortModel is not a function
my code
onSortChanged={useCallback(e => console.log(e.api.getSortModel(), 'im from sort'))}
"#ag-grid-community/react": "27.3.0",
"#ag-grid-enterprise/all-modules": "27.3.0",
After spend some time found params.api.getSortModel() is deprecated after version 24.0.0.
Using Column state for get Sort model and set Sort model in the following way
getSortModel:
const onSortChanged = useCallback(() => {
const value = gridParams.columnApi.getColumnState().find(s => s.sort != null)
if (value) {
setSortModel([ value ])
} else {
setSortModel([])
}
}, [ gridParams, setSortModel ])
setSortModel:
useEffect(() => {
if (sortModel.length > 0) {
const curretSortModel = gridParams.columnApi.getColumnState()
const mergeSortModel = curretSortModel.map(o1 => sortModel.find(o2 => o2.colId === o1.colId) || o1)
gridParams.columnApi.setColumnState(mergeSortModel)
}
}, [gridParams, sortModel]
As per this plunkr, you can retrieve and apply sort with the following example: https://plnkr.co/edit/?open=index.jsx&preview
const sortByAthleteDesc = useCallback(() => {
gridRef.current.columnApi.applyColumnState({
state: [{ colId: 'athlete', sort: 'desc' }],
defaultState: { sort: null },
});
}, []);
const saveSort = useCallback(() => {
var colState = gridRef.current.columnApi.getColumnState();
var sortState = colState
.filter(function (s) {
return s.sort != null;
})
.map(function (s) {
return { colId: s.colId, sort: s.sort, sortIndex: s.sortIndex };
});
savedSort = sortState;
console.log('saved sort', sortState);
}, []);

can't synchronise the updated Products List array in zustand?

I want to explain the use case i have so you can understand it well
I have Cart & Products when the user adds the product (product_id = 1) twice to the cart and the product has the same options (red, xl) I increment the quantity,
if the user adds the same (product_id = 1) but with other options (green, xl), I add this product to the cart as a separate product.
Now this works well!
but when the user after added the above 2 products and add the same product with the same option (red, xl) again, It's added as a separated product!
What I expected if the product options existing before should increment the quantity otherwise added it as a separate.
What i tried
add the option ids into the Product property and check if it exists before or not then handle what I want but it does not work well and added the third product as a separate one!
Screen Record
code snippet
zustand Store
interface CartProductsProp extends State {
cartProducts: ProductProps[];
addToCart: (Products: ProductProps) => void;
updateProductQuantity: (
Product: ProductProps,
updatedQuantity: number,
) => void;
checkProductOptionsExist: (
Product: ProductProps,
updatedQuantity: number,
) => void;
...
}
export const useCartProduct = create<CartProductsProp>(
persist(
(set, get) => ({
cartProducts: [],
addToCart: (product) => {
set((prev) => ({
cartProducts: [...prev.cartProducts, {...product}],
}));
},
checkProductOptionsExist: (
product: ProductProps,
updatedQuantity: number,
) => {
set((prev) => {
console.log('->prev', JSON.stringify(prev.cartProducts));
console.log(
'check==>IDs',
cartProduct.id === product.id &&
product.productOptionIds === cartProduct.productOptionIds,
); // for some reason this run towic when add the third product"with same options as first product "red,xl" true then false
return prev.cartProducts.map((cartProduct) => {
cartProduct.id === product.id &&
product.productOptionIds === cartProduct.productOptionIds
? get().updateProductQuantity(product, updatedQuantity)
: get().addToCart(product);
});
});
},
// To Update the quantity when product exist in cart before
updateProductQuantity: (
product: ProductProps,
updatedQuantity: number,
) => {
set((prev) => {
let currentCart = prev.cartProducts.map((cartProduct) =>
cartProduct.id === product.id &&
areEqual(cartProduct.selectedOptions, product.selectedOptions)
?
{
...product,
quantity: cartProduct?.quantity! + updatedQuantity,
updated: 'yes#',
productTotalPrice:
(cartProduct?.quantity! + updatedQuantity) *
cartProduct.price,
}
: cartProduct,
);
console.log('##currentCart', JSON.stringify(currentCart));
return {
cartProducts: currentCart,
};
});
...
},
}),
{
name: 'cartListProduct-local',
getStorage: () => AsyncStorage,
},
),
);
Product Details
const addProductToCart = () => {
let productOptionIds = allOptions
.map(({id}: {id: number | string}) => id)
.sort()
.join(',');
let currentProduct = {
...item,
id: item.id,
product_id: item.id,
quantity: currentQuantity,
price: updatedPrice,
productTotalPrice: updatedPrice * currentQuantity,
selectedOptions: allOptions,
productOptionIds: productOptionIds,
};
setAddToCartLoading(true);
if (
!cartProductList.some((alreadyExist) => alreadyExist.id === item.id)
) {
addToCart(currentProduct);
Alert.alert(t('addedSuccessfully'));
setAddToCartLoading(false);
} else {
checkProductOptionsExist(currentProduct, currentQuantity);
Alert.alert(t('addedSuccessfully'));
}
};
Utility
export const areEqual = (a: arrayProps = [], b: arrayProps = []): boolean => {
// compare length of arrays
if (a.length !== b.length) {
return false;
}
// get ids set in b
const idsSetInB = new Set(b.map(({id}: {id: number | string}) => id));
console.log('idsSetInB', idsSetInB);
// iterate over a, and check if the id of an item is not in b
for (let {id} of a) {
if (!idsSetInB.has(id)) {
return false;
}
}
// if it passes all the items, return true
return true;
};
I just add the checks in the Product Details, not in the store,
first, get the targeted product from the Cart so I can here check if it exists before or not based on the optionsIDs if the return undefined that's mean the product + options, not in the cart so I add it as a separated product otherwise I update the quantity and it works well.
Maybe I can't do this in the store itself checkProductOptionsExist, (if u have any explanation tell me please)
If u have an any better idea do it please ;)
...
if (
!cartProductList.some((alreadyExist) => alreadyExist.id === item.id)
) {
addToCart(currentProduct);
Alert.alert(t('addedSuccessfully'));
setAddToCartLoading(false);
}
else {
let res = cartProductList.find(
(currentProd) =>
currentProd.product_id === currentProduct.product_id &&
currentProd.productOptionIds === currentProduct.productOptionIds, // or areEqual FC ;)
);
res != null
? updateProductQuantity(currentProduct, currentQuantity)
: addToCart(currentProduct);
setAddToCartLoading(false);
Alert.alert(t('addedSuccessfully'));
}
store
....
updateProductQuantity: (
product: ProductProps,
updatedQuantity: number,
) => {
set((prev) => {
let currentCart = prev.cartProducts.map((cartProduct) =>
cartProduct.id === product.id &&
areEqual(cartProduct.selectedOptions, product.selectedOptions)
? {
...product,
quantity: cartProduct?.quantity! + updatedQuantity,
productTotalPrice:
(cartProduct?.quantity! + updatedQuantity) *
cartProduct.price,
}
: cartProduct,
);
return {
cartProducts: currentCart,
};
});
},
....

List sorting method not updating order

I'm trying to get some insight into why this sort function isn't working.
In theory, it should work the same as this: https://codepen.io/levit/pen/abmXgBR
I have a list I'm grabbing from an API:
<BookCard v-for='book in filteredBooks' :key='book.id' :book='book' />
I've got a filter for search working, but my sort isn't. Here is my data with computed properties/methods:
data() {
return {
books: [],
order: 1, // Ascending
search: '',
};
},
computed: {
filteredBooks() {
return this.filterBySearch((this.sortByRating(this.books)));
},
},
methods: {
filterBySearch(books) {
return books.filter((book) => book.volumeInfo.title
.toLowerCase().match(this.search.toLowerCase()));
},
sortByRating(books) {
return books
.sort((r1, r2) => (r2.volumeInfo.averageRating - r1.volumeInfo.averageRating)
* this.order);
},
sort() {
this.order *= -1;
},
},
Finally, I have a button to switch the order:
<button v-bind:class="order === 1 ? 'descending' : 'ascending'" #click="sort">
Reader Rating
</button>
Any insight into what I might be getting wrong would be very helpful as I'm new to Vue.
Thank you.
Try to not pass the data property as an argument since it's available inside the methods and just sort the filtered books not the original property because the sort affects it :
computed: {
filteredBooks() {
let filtered= this.filterBySearch().slice();
return this.sortByRating(filtered)
},
},
methods: {
filterBySearch() {
return this.books.filter((book) => book.volumeInfo.title
.toLowerCase().match(this.search.toLowerCase()));
},
sortByRating(books) {
return books.sort((r1, r2) => {
if (
typeof r2.volumeInfo.averageRating === "number" &&
typeof r1.volumeInfo.averageRating === "number"
) {
return (
(r2.volumeInfo.averageRating - r1.volumeInfo.averageRating) *
this.order
);
} else {
return this.order * -1;
}
});
},
sort() {
this.order *= -1;
},
},

Grouping together similar lines of code in the code below for some array filtering

I am repeatedly using same array filter functionality in my if else conditions however only the properties differ in each case. Is there a way to group them together or is it right the way it is below?
private _filter(value: string, filterIndex, type: string): string[] {
let filterArray = [];
const filterValue = value.toLowerCase();
if (filterIndex == 0) { // Index for Type
if (type === 'Dsc') {
this.assetTypeData.filter((option) => option.assetTypeDsc.toLowerCase().includes(filterValue)).forEach(element => {
filterArray.push(element.assetTypeDsc)
});
} else {
this.assetTypeData.filter((option) => option.assetTypeCde.toLowerCase().includes(filterValue)).forEach(element => {
filterArray.push(element.assetTypeCde)
});
}
} else if (filterIndex == 1) { // Index for Make
if (type === 'Dsc') {
this.assetMakeData.filter((option) => option.assetMakeDsc.toLowerCase().includes(filterValue)).forEach(element => {
filterArray.push(element.assetMakeDsc)
});
} else {
this.assetMakeData.filter((option) => option.assetMakeCde.toLowerCase().includes(filterValue)).forEach(element => {
filterArray.push(element.assetMakeCde)
});
}
}
tried to group everything that could be grouped
private _filter(value: string, filterIndex, type: string): string[] {
const filterValue = value.toLowerCase();
return (filterIndex == 0 ? this.assetTypeData : this.assetMakeData)
.map(option => option[(filterIndex == 0 ? 'assetType': 'assetMake') + type])
.filter(assetValue => assetValue.toLowerCase().includes(filterValue));
}

Filter with map but keep the indice

I wanna to filter and then map the array of object, but when do this the filter make a new array and give me different indices, is possible to do this using filter or should i use another way.
this.props.todos = [
{
task:'Daily meet',
status:'incomplete'
},
{
task:'Play videogame'
status:'complete'
}
]
this.props.todos.filter(todos => todos.status === 'complete').map((todos, i) => {
return (<p>{todos.status} - Everythin Ok</p>)
//here i got i = 0
}));
this.props.todos.filter(todos => todos.status === 'incomplete').map((todos, i) => {
return (<p>{todos.status} - You have some task incomplete</p>)
//and here i got i = 0 too i wanna this to be like the original array
}));
Just use map, no need to filter. You can return either component like this:
this.props.todos = [
{
task: 'Daily meet',
status: 'incomplete'
},
{
task: 'Play videogame'
status: 'complete'
}
]
this.props.todos.map(todo => {
if (todo.status === 'complete') {
return (<p>{todo.status} - Everythin Ok</p>);
}
if (todo.status === 'incomplete') {
return (<p>{todo.status} - You have some task incomplete</p>);
}
return null;
})

Categories

Resources