Part of learning Fanatasy Land/Folk Tale has lead me to creating some code. I am essnetially scnaning my network (via someLib) and uploading the results to a mongo repository. The scan returns back an array of results, while the upsert into mongo needs to work on results independently (mongoose - this is my first time with this lib too, so I may be mistaken there). In a traditional promised base model I would
// step 0: setup
const someLibPomise = makePromiseOf(someLib)
//set 1: get data
const dataArray = yield someLibPomise()
//set 2: convert to array of promises to upsert
const promiseArray = _.map(dataArray, makeUpsertPromise)
//step 3: wait on results
const upsertResults = yield promiseArray
In and of itself, this is a pretty clean representation, but I want push my comprehension of these functional techniques. My working version leaves a little bit to be desired, as I cant seem to get from the Task returned by the someLibTask function, which contains an array of objects TO an array of Tasks representing the individual upserts. I feel there must be a better way here is what is working:
// step 0: setup
const someLibTask = Async.liftNode(someLib)
const cleanUpData = (dataArray) => {
return _.map(dataArray, (data) => {
// cleanup data object
return data
})
}
const upsertTask = (collection) => {
return (criteria, record) => {
return new Task( (reject, resolve) => {
const callback = (error, data) => {
if (error) reject(error)
else resolve(data)
}
collection.findOneAndUpdate(criteria, record,
{upsert: true}, callback)
})
}
}
const persist = (data) => {
mongoose.connect('mongodb://localhost/db');
const someUpsert = adapt.upsertTask(Some.collection)
const tasks = _.map(data, (record) => {
const criteria = { "id": record.id }
return serverUpsert(criteria, record)
})
return Async.parallel(tasks).fork(console.error, process.exit)
}
// step 1: make a query and return an array of objects
// () => Task(object[])
const dataTask = someLibTask().map(cleanUpData)
// step 2: for the results to error log or persist method
// (d) => (), (d) => ()
dataTask.fork(console.error, persist)
Ideally i can chain (or map) the results from the dataTask into persist, which converts that individual task to an array of upsert tasks. Which I can then wait on. I would love to see something like:
// step 1: make a query and return an array of objects
const dataTask = someLibTask().map(cleanUpData)
// step 2: chain the results into upsert
const upsertTasks = dataTask.chain(persist)
//step 3: wait on the upsert tasks, and then log results
Async.parallel(upsertTasks).fork(console.error, process.exit)
That's impossible. You cannot get out of the
Task
monad. For knowing how many Tasks you would get in that array, you would need to run the initial task first.What you want seems to be
which returns another Task for the result of all upserts.