Is there a way to create a chained object from loop? For example input:
["table1","table2","table3"]
output:
db
.select(fields)
.from(table)
.innerJoin("table1")
.innerJoin("table2")
.innerJoin("table3")
another input:
["table1","table2","table3","table4","table5"]
output:
db
.select(fields)
.from(table)
.innerJoin("table1")
.innerJoin("table2")
.innerJoin("table3")
.innerJoin("table4")
.innerJoin("table5")
Right now i have no idea how to do that except using eval, which isn't something i would like to do.
I need this to join multiple tables using knex, so if there any other way to do so, i will be really happy :)
I think looking into functional programming will help you here.
I used a pipe function from the internet link below but you could use lodash/Ramda/underscore or whatever your fav util library is.
the two main concepts I'm using here is currying and piping.
What is 'Currying'? Currying is when you break down a function that takes multiple arguments into a series of functions that take part of the arguments we are also making use of curring which is returning a function from another function to compose new functions.
https://medium.com/@venomnert/pipe-function-in-javascript-8a22097a538e A pipe function takes an n sequence of operations; in which each operation takes an argument; process it; and gives the processed output as an input for the next operation in the sequence. The result of a pipe function is a function that is a bundled up version of the sequence of operations.
what we're doing here is taking an array, creating a new array of functions we want to apply to a value.
So we want to do a load of joins on a db.
join => con => con.innerJoin(join);
is taking a value i.e "table1" and returning a function that takes a db connection which calls the join and returns for the next one.
const joins = toJoin.map(join => con => con.innerJoin(join));
and this creates are array of functions to pass to pipe.
const db = ({
select: function (field) {
console.log('select', field)
return db
},
from: function (table) {
console.log('from', table)
return db;
},
innerJoin: function (join) {
console.log('innerJoin', join)
return db;
}
});
const _pipe = (a, b) => (arg) => b(a(arg));
const pipe = (args) => [].slice.apply(args).reduce(_pipe);
function joinInnerMultiple(table, fields, toJoin) {
const joins = toJoin.map(join => con => con.innerJoin(join));
return pipe(joins)(db.select(fields).from(table));
}
joinInnerMultiple("User", "uuid", ["table1", "table2", "table3", "table4", "table5"])