Ramda, filter with or condition - ramda.js

let arr = [
{
name: 'Anna',
q: {
name: 'Jane'
}
}
];
const getName = R.prop('name');
const getQname = R.path(['q','name']);
A filter where any of these two functions passes.
Something like:
export const filterByName = (name) =>
R.filter(
R.or(
R.propEq(getName, name),
R.propEq(getQname, name)
)
)
Not working. How can I combine these two functions in a R.filter?

Use R.either with R.propEq for the name and R.pathEq from q.name:
const filterByName = (name) =>
R.filter(
R.either(
R.propEq('name', name),
R.pathEq(['q', 'name'], name)
)
)
const arr = [{"name":"Anna","q":{"name":"Jane"}},{"name":"Smite","q":{"name":"Jane"}},{"name":"Another","q":{"name":"One"}}];
console.log(filterByName('Anna')(arr))
console.log(filterByName('Jane')(arr))
console.log(filterByName('XXX')(arr))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
If you want to use an external function to extract the values, you can use R.pipe. Extract all property values with R.juxt, and then use R.any with R.equal to check for equality.
const getName = R.prop('name');
const getQname = R.path(['q','name']);
const filterByName = (name) =>
R.filter(
R.pipe(
R.juxt([getName, getQname]), // get all names
R.any(R.equals(name)) // check if any of the equals to name
)
)
const arr = [{"name":"Anna","q":{"name":"Jane"}},{"name":"Smite","q":{"name":"Jane"}},{"name":"Another","q":{"name":"One"}}];
console.log(filterByName('Anna')(arr))
console.log(filterByName('Jane')(arr))
console.log(filterByName('XXX')(arr))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

I would use either as it works with functions:
export const filterByName = (name) =>
R.filter(R.either(
R.propEq('name', name),
R.pathEq(['q', 'name'], name)));
or
const nameIs = R.propEq('name');
const qNameIs = R.pathEq(['q','name']);
export const filterByName = (name) =>
R.filter(R.either(nameIs(name), qNameIs(name)));

You could also write this in a point free style:
const nameIs = R.converge(R.or, [
R.pathEq(['name']),
R.pathEq(['q', 'name']),
]);
const onlyAnna = R.filter(nameIs('Anna'));
const onlyGiuseppe = R.filter(nameIs('Giuseppe'));
const data = [
{ name: 'Anna', q: { name: 'Jane' } },
{ name: 'Mark', q: { name: 'Mark' } },
{ name: 'Giuseppe', q: { name: 'Hitmands' } },
];
console.log('Anna', onlyAnna(data));
console.log('Giuseppe', onlyGiuseppe(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

Related

what should i use istead of ans if i want to make a list?

what should i use istead of ans if i want to make a list? I tried putting more ans var but it doesn't work only displays the last ans
<script setup>
import { ref } from "#vue/reactivity";
const faqToggle = ref(false);
const faqItems = ref([
** {
title: "test",
ans: "· test1",
id: 1,
},**
]);
const id = ref(null);
const toggle = (fid) => {
if (fid === id.value) {
faqToggle.value = !faqToggle.value;
} else {
faqToggle.value = true;
}
id.value = fid;
};
</script>
title: "test",
ans: "· test1",
ans: "· test2",
ans: "· test3",
ans: "· test4",
id: 1,

multiple select data in object format

I have a multiple select field where I'll be selecting multiple values, but when I am sending that data to the backend it should show in the following format:
"data":
[
{
"vehicle_id": "VEH1",
},
{
"vehicle_id": "VEH2",
},
]
but when I am selecting multiple values from drop down I am getting data in an array format:
"data":[
{
"vehicle_id":["VEH1","VEH2"]
}
]
How can I send data in the format which I have added in the beginning? .
Code:
const getSelectedVehices = (selectedvehicles: any[]) => {
const vehicles: Array<string> = [];
const items = new Map<string, string>();
vehicleListData.forEach((item) => {
items.set(item.vehicleName, item.vehicleAliasId);
});
selectedvehicles.forEach((item) => {
vehicle.push(items.get(item) || '');
});
return vehicles;
};
const prepareSelectedVehiclesServices = (electedvehicles: any[]) => {
const vehicles: Array<string> = [];
const items = new Map<string, string>();
vehicleListData.forEach((item) => {
items.set(item.vehicleName, item.vehicleAliasId);
});
vehicles.forEach((item) => {
if (items.has(item)) {
vehicles.push(items.get(item) || '');
}
});
return vehicles;
};
<MultiSelect
items={pickerOptions.vehicleServices}
onSelectedItemsChange={(Ids: any[]) => {
const selectedVehiclesServices = getSelectedVehicles(Ids);
formikData.setFieldValue(`vehicles`, [
{
vehicleAliasId: selectedVehiclesServices,
},
]);
}}
selectedItems={{
selectedItemIdentifiers: prepareSelectedVehiclesServices(
formikData.values.services || initialServiceValues.services,
),
}}
></MultiSelect>
the above is the code which I have added.
Just project the array into your new format with .map(). Something like this:
let myData = { "data":[
{
"vehicle_id":["VEH1","VEH2"]
}
]};
let myNewData = { "data": myData.data[0].vehicle_id.map(d => ({
"vehicle_id": d
}))};
console.log(myNewData);

How do I resolve a callback error with 'callback' is an instance of Object)?

TypeError: callback is not a function. (In 'callback(data)',
'callback' is an instance of Object)
The code here works just fine when I write it like this:
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
// { categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
When i uncomment that other line, it breaks and gives me this error.
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
{ categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
Here is the relevant snippet from listingsAPI (below) if it helps but this code works fine when there is only one object. Is there a specific way to make this work with two objects like above?
if (categoryId) {
return (
listingsRef
.where('categoryID', '==', categoryId)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
if (categoryId2) {
return (
listingsRef
.where('categoryID2', '==', categoryId2)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
You can combine your queries via this way if you want to have it optional:
let query = listingsRef.where('isApproved', '==', isApproved)
if (categoryId) {
query = query.where('categoryID', '==', categoryId)
}
if (categoryId2) {
query = query.where('categoryID2', '==', categoryId2)
}
query.onSnapshot...

typeError object(...) is not a function

I get the "object is not a function" error on the line where the "setup()" function appears.
I have no clue how to debug this... Am I doing something wrong? (I'm not an experimented developer, so I know I'm doing things wrong, but here, I have no clue what it is...)
It's asking me to add more details because my post is mainly code... So I'm writing this, but I habe idea what details I could c=possibly add. :-)
Thanks in advance for your help!!
<script>
import { ref } from 'vue'
import Ftable from '#/components/tables/Ftable.vue'
import Searchbar from '#/components/tables/Searchbar.vue'
import getMainCollection from '#/composables/getMainCollection'
export default {
name: 'Home',
components: { Searchbar, Ftable },
setup(){ //error arrives on this line
const { getData, getMore } = getMainCollection()
const documents = ref('')
const lastVisible = ref('')
const type = ref('')
const country = ref('')
function newSearch() {
const {doc, last} = getData(type, country)
documents.value = doc
lastVisible.Value = last
}
function askForMore() {
const { doc, last } = getMore(type, country, lastVisible)
documents.value = doc
lastVisible.value = last
}
return { documents, askForMore, newSearch, askForMore }
}
}
</script>
import { ref } from 'vue'
import { projectFirestore } from '#/firebase/config'
const getMainCollection = () => {
const collectionGroupRef = projectFirestore.collectionGroup('users')
const lastVisible = ref('')
const documents = ('')
function getData(type, country) {
const filter = null
if (type != null && country == null){
filter = collectionGroupRef.where('type', '==', `${type}`)
}
else if(type == null && country != null){
filter = collectionGroupRef.where('country', '==', `${country}`)
}
else{
filter = collectionGroupRef
}
const data = filter.orderBy('createdAt')
.limit(2)
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
documents.value.push({ ...doc.data(), id: doc.id})
})
lastVisible = querySnapshot.docs[querySnapshot.docs.length-1]
})
return( documents, lastVisible)
}
function getMore(type, country, lastVisible) {
const filter = null
if (type != null && country == null){
filter = collectionGroupRef.where('type', '==', `${type}`)
}
else if(type == null && country != null){
filter = collectionGroupRef.where('country', '==', `${country}`)
}
else{
filter = collectionGroupRef
}
filter.startAfter(lastVisible)
.limit(2)
.orderBy(createdAt)
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
documents.value.push({ ...doc.data(), id: doc.id })
})
lastVisible = querySnapshot.docs[querySnapshot.docs.length-1]
})
return( documents, lastVisible)
}
return ( getData, getMore )
}
export { getMainCollection }
Since you exported getMainCollection as an object:
export { getMainConnection }
You need to destructure it when importing:
import { getMainCollection } from '#/composables/getMainCollection'

React Native navigation param doesn't get updated value

I have a React Native application where i'm taking input from one component and sending the input values as navigation params to other component where search is performed according to those input data. Now, it's working on first time when i'm getting the input values from receiving them with navigation.getParam.But when i go back to add some new inputs and go to the other component navigation.getParamshows the older value not the current one. Here's where i'm taking the inputs:
inputData = () => {
let bodyData = {
customer_id: this.state.customerId,
security_code: this.state.userSecurityCode,
vendor: this.state.vendor,
category_id: this.state.categoryName,
country_id: this.state.countryName,
zone_id: this.state.zoneName,
navigationIdentity: 1
}
this.props.navigation.navigate('Vendor',bodyData)
}
And here's i'm receiving:
componentWillMount() {
const { navigation } = this.props;
this.focusListener = navigation.addListener("didFocus", () => {
const customer_id = navigation.getParam('customer_id')
const security_code = navigation.getParam('security_code')
const vendor = navigation.getParam('vendor')
const category_id = navigation.getParam('category_id')
const country_id = navigation.getParam('country_id')
const zone_id = navigation.getParam('zone_id')
let searchBody = {
customer_id: customer_id,
security_code: security_code,
vendor: vendor,
category_id: category_id,
country_id: country_id,
zone_id: zone_id
}
console.log('in focus',searchBody)
});
}
Now the console.log here only shows the first input values received with navigation.getParam. After that when i update input values and navigate it still shows the first fetched values.
Hope this works
inputData = () => {
let bodyData = {
customer_id: this.state.customerId,
security_code: this.state.userSecurityCode,
vendor: this.state.vendor,
category_id: this.state.categoryName,
country_id: this.state.countryName,
zone_id: this.state.zoneName,
navigationIdentity: 1
}
this.props.navigation.push('Vendor',bodyData)
}
componentWillMount() {
const { params } = this.props.navigation.state;
this.focusListener = this.props.navigation.addListener("didFocus", () => {
const customer_id = params.customer_id;
const security_code = params.security_code;
const vendor = params.vendor;
const category_id = params.category_id;
const country_id = params.country_id;
const zone_id = params.zone_id;
let searchBody = {
customer_id: customer_id,
security_code: security_code,
vendor: vendor,
category_id: category_id,
country_id: country_id,
zone_id: zone_id
}
console.log('in focus',searchBody)
});
}