Hello Developers,
I’m currently developing an app that utilizes Firebase for database operations. In this application, I retrieve data using queries that are determined by various filter and ordering conditions set by the users. There are numerous conditions representing all possible search queries within the app.
To enhance the codebase, I’m seeking to create a function that dynamically checks these conditions and generates queries based on the user-defined criteria. Instead of having separate functions for each specific condition, I’m looking for a more efficient and DRY (Don’t Repeat Yourself) approach, where a single function can dynamically construct queries based on varying conditions.
I’ll provide snippets of my code where I’ve previously created dedicated functions for specific conditions. I’d appreciate your insights and suggestions on how to refactor this code, making it more modular and maintainable by developing a function that dynamically generates queries based on the given conditions.
Thank you for your assistance!
async function getPageinatedDocsInDb(offset, catId, priceMin, priceMax, orderFilter){
const catIdNum = catId?parseInt(catId):null
const priceMinNum = priceMin?parseInt(priceMin):0
const priceMaxNum = priceMax?parseInt(priceMax):2000
let tempArr =
const productsRef = collection(db, "all-products")
function allProductsQuery(x){
// all products
return query(
productsRef,
limit(x)
)
}
function allProductsQueryStartAt(x,y){
// all products with start after property
return query(
productsRef,
startAfter(y),
limit(x)
)
}
function allProductsSortPriceAscQuery(x){
// all products price ascending
return query(
productsRef,
orderBy("price"),
limit(x)
)
}
function allProductsSortPriceAscQueryStartAt(x,y){
// all products price ascending with start after property
return query(
productsRef,
orderBy("price"),
startAfter(y),
limit(x)
)
}
function allProductsSortPriceDecQuery(x){
// all products price decending
return query(
productsRef,
orderBy("price", "desc"),
limit(x)
)
}
function allProductsSortPriceDecQueryStartAt(x,y){
// all products price descending with start after property
return query(
productsRef,
orderBy("price", "desc"),
startAfter(y),
limit(x)
)
}
function priceQuery(x){
// all products price filter
return query(
productsRef,
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
limit(x)
)
}
function priceQueryStartAt(x,y){
// all products price filter
return query(
productsRef,
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
StartAt(y),
limit(x)
)
}
function priceQuerySortPriceAsc(x){
// all products price filter order by price ascending
return query(
productsRef,
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price"),
limit(x)
)
}
function priceQuerySortPriceAscStartAt(x,y){
// all products price filter order by price ascending
return query(
productsRef,
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price"),
startAfter(y),
limit(x)
)
}
function priceQuerySortPriceDec(x){
// all products price filter order by price descending
return query(
productsRef,
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price", "desc"),
limit(x)
)
}
function priceQuerySortPriceDecStartAt(x,y){
// all products price filter order by price descending
return query(
productsRef,
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price", "desc"),
startAfter(y),
limit(x)
)
}
function categoryQuery(x){
// all products category filter
return query(
productsRef,
where("category.id", "==", catIdNum),
limit(x)
)
}
function categoryQueryStartAt(x,y){
// all products category filter with start after property
return query(
productsRef,
where("category.id", "==", catIdNum),
startAfter(y),
limit(x)
)
}
function categoryQuerySortPriceAsc(x){
// all products category filter sorted by price ascending
return query(
productsRef,
where("category.id", "==", catIdNum),
orderBy("price"),
limit(x)
)
}
function categoryQuerySortPriceAscStartAt(x,y){
// all products category filter sorted by price ascending with start after property
return query(
productsRef,
where("category.id", "==", catIdNum),
orderBy("price"),
startAfter(y),
limit(x)
)
}
function categoryQuerySortPriceDec(x){
// all products category filter sorted by price descending
return query(
productsRef,
where("category.id", "==", catIdNum),
orderBy("price", "desc"),
limit(x)
)
}
function categoryQuerySortPriceDecStartAt(x,y){
// all products category filter sorted by price descending with start after property
return query(
productsRef,
where("category.id", "==", catIdNum),
orderBy("price", "desc"),
startAfter(y),
limit(x)
)
}
function categoryAndPriceQuery(x){
// all products category and price filter
console.log('products category and price filter')
return query(
productsRef,
where("category.id", "==", catIdNum),
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
limit(x)
)
}
function categoryAndPriceQueryStartAt(x,y){
// all products category and price filter with start after property
return query(
productsRef,
where("category.id", "==", catIdNum),
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
startAfter(y),
limit(x)
)
}
function categoryAndPriceQuerySortPriceAsc(x){
// all products category and price filter sort by price ascending
return query(
productsRef,
where("category.id", "==", catIdNum),
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price"),
limit(x)
)
}
function categoryAndPriceQuerySortPriceAscStartAt(x,y){
// all products category and price filter sort by price ascending with start at property
return query(
productsRef,
where("category.id", "==", catIdNum),
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price"),
startAfter(y),
limit(x)
)
}
function categoryAndPriceQuerySortPriceDec(x){
// all products category and price filter sort by price decending
console.log('all products category and price filter sort by price decending')
return query(
productsRef,
where("category.id", "==", catIdNum),
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price", "desc"),
limit(x)
)
}
function categoryAndPriceQuerySortPriceDecStartAt(x,y){
// all products category and price filter sort by price decending with start at property
console.log('all products category and price filter sort by price decending with start at property')
return query(
productsRef,
where("category.id", "==", catIdNum),
where("price", ">=", priceMinNum),
where("price", "<=", priceMaxNum),
orderBy("price", "desc"),
startAfter(y),
limit(x)
)
}
if (offset!==0){
// if not first page
console.log('not first page')
if(catId&&priceMin&&priceMax&&orderFilter){ // if all filter and sort fields // condition 1
console.log('all fields')
if(orderFilter==="dec-price"){ // if sorting by price decending
console.log('dec price')
const first = categoryAndPriceQuerySortPriceDec(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = categoryAndPriceQuerySortPriceDecStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if (orderFilter==="asc-price"){
// else if sorting by price ascending
const first = categoryAndPriceQuerySortPriceAsc(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = categoryAndPriceQuerySortPriceAscStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else if(catId&&priceMin&&priceMax){
// if category and price filters //condition 2
const first = categoryAndPriceQuery(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = categoryAndPriceQueryStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(catId&&orderFilter){
// if category filter and sorted by price // condition 3
if(orderFilter==="asc-price"){
const first = categoryQuerySortPriceAsc(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = categoryQuerySortPriceAscStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter==="dec-price"){
const first = categoryQuerySortPriceDec(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = categoryQuerySortPriceDecStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else if(priceMin&&priceMax&&orderFilter){
// if filtering by price and sorting by price // condition 4
if(orderFilter==="asc-price"){
// if sorting by ascending price
const first = priceQuerySortPriceAsc(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = priceQuerySortPriceAscStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter==="dec-price"){
//if sorting by decending price
const first = priceQuerySortPriceDec(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = priceQuerySortPriceDecStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else if(priceMin&&priceMax){
// if price filter // condition 5
const first = priceQuery(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = priceQueryStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if (catId){
// if filter by category // condition 6
const first = categoryQuery(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = categoryQueryStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter){
// if no filter sort by price // condition 7
if(orderFilter==="asc-price"){
// if sorting by ascending price
const first = allProductsSortPriceAscQuery(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = allProductsSortPriceAscQueryStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter==="dec-price"){
// if sorting by descending price
const first = allProductsSortPriceDecQuery(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = allProductsSortPriceDecQueryStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else {
// no filters and no sotring condition 8
const first = allProductsQuery(offset)
const firstPageSnap = await getDocs(first)
const lastIndexdoc = firstPageSnap.docs[firstPageSnap.docs.length-1]
const next = allProductsQueryStartAt(9,lastIndexdoc)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else{
console.log('first page')
if(catId&&priceMin&&priceMax&&orderFilter){ // if all filter and sort fields
if(orderFilter==="dec-price"){ // if sorting by price decending
const next = categoryAndPriceQuerySortPriceDec(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if (orderFilter==="asc-price"){ // if sorting by price ascending
const next = categoryAndPriceQuerySortPriceAsc(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else if(catId&&priceMin&&priceMax){ // if category and price filters
console.log('category and price filters')
const next = categoryAndPriceQuery(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(catId&&orderFilter){
// if category and sorted by price
if(orderFilter==="asc-price"){
// if sorting ascending
const next = categoryQuerySortPriceAsc(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter==="dec-price"){
// if sorting decending
const next = categoryQuerySortPriceDec(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else if(priceMin&&priceMax&&orderFilter){
// if filtering by price and sorting by price
if(orderFilter==="asc-price"){
// if sorting by ascending price
const next = priceQuerySortPriceAsc(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter==="dec-price"){
//if sorting by decending price
const next = priceQuerySortPriceDec(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else if(priceMin&&priceMax){
// if price filter
const next = priceQuery(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(catId){
// if category
const next = categoryQuery(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter){
// if no filter sort by price
if(orderFilter==="asc-price"){
// if sorting by ascending price
const next = allProductsSortPriceAscQuery(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
else if(orderFilter==="dec-price"){
// if sorting by descending price
const next = allProductsSortPriceDecQuery(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
else {
// no filters and no sotring
const next = allProductsQuery(9)
const querySnapshot = await getDocs(next)
querySnapshot.forEach((doc) => {
const data = doc.data()
data.id = doc.id
tempArr.push(data)
})
}
}
return tempArr
}