Get value from nested functions in Coffeescript - coffeescript

i want to get a result from another function (anonymous-function), but i don't know how because my result-function is a nested function. Maybe I have to use a callback somehow?
Here my code:
render: ->
console.log #getCommunities()
return this
getCommunities: ->
dpd.communities.get (result, err) ->
return console.log(err) if err
result
getCommunities() returns always 'undefined'.
Does anyone know how to solve this problem?
Thanks,
rojan

How about this?
render: ->
#getCommunities (err, result) ->
if err then throw err
console.log result
return this
getCommunities: (callback) ->
dpd.communities.get (result, err) ->
return console.log(err) if err
callback(null, result)
fyi, it's a best practice to pass err as the first arg to callbacks in node, assuming this is in fact node...just guessing by the err callback

Related

What is the difference between the following two codes when using mongo driver in Golang?

Currently I'm working on a project, and I'm looking for a better way to source code.
I wonder What is Different,
func (db *Database) FindData(ctx context.Context, filter *Data) (*Data, error) {
col := db.client.Database(DefaultDatabase).Collection(COLLECTION_DATA)
var data Data
err := col.FindOne(ctx, filter).Decode(&data)
if err != nil {
return nil, err
}
return &data, nil
}
and
func (db *Database) FindData(ctx context.Context, filter *Data) (*Data, error) {
col := db.client.Database(DefaultDatabase).Collection(COLLECTION_DATA)
res := col.FindOne(ctx, filter)
if err:= res.Err(); err != nil {
return nil, err
}
var data Data
err := res.Decode(&reason)
return &data, err
}
What are the possible differences, and which code is better?
I verified that both sources were the same, and realized that I didn't have to use the long version.
There is no need to implement ERROR processing because ERROR processing of the corresponding result is carried out in Decode().
Thanks for Comment :) Burak Serdar

How should Go Context be declared?

Suppose I have a file that modifies database, should the functions share a single context or should each function have their own context?
Sharing context
var (
ctx = context.Background()
)
func test1() {
res, err := Collection.InsertOne(ctx, data)
}
func test2() {
res, err := Collection.InsertOne(ctx, data)
}
Or should it be like this?
func test1() {
res, err := Collection.InsertOne(context.Background(), data)
}
func test2() {
res, err := Collection.InsertOne(context.Background(), data)
}
Neither. Your context should be request-scoped (for whatever "request" means in your application) and passed down the call chain to each function.
func test1(ctx context.Context) {
res, err := Collection.InsertOne(ctx, data)
}
func test2(ctx context.Context) {
res, err := Collection.InsertOne(ctx, data)
}
If you're building a web server, as indicated in comments, you'll usually get your context from the HTTP request in your handler:
func myHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// now pass ctx to any fuction that needs it. This way, if the HTTP
// client/browser cancels the request, your downstream functions will
// be able to abort immediately, without wasting time finishing their
// work.
}
You should not use the first approach. Context is something to be passed down to functions, it should not be declared as a global variable.
The second approach can be used at times, especially if there is no request context. However, if multiple calls are handled within a single server context, you should pass down the context for that call to all the other calls getting a context, so when the context is canceled or expired, all calls would fail.

Is it possible to call Go functions in one transactions?

I store a double linked list in PostgreSQL. I have a Go API to manage this list.
There is a function that creates new Node (in specific position). Let's assume there is an INSERT SQL query inside of it.
Also, there is a function that deletes Node (by id). Let's assume there is a DELETE SQL query inside of it.
It is well known that if you need to move a Node to different position you should call DeleteNode() function and CreateNode() function. So there is the third function called MoveNode()
func MoveNode() error {
if err := DeleteNode(); err != nil {
return err
}
if err := CreateNode(); err != nil {
return err
}
return nil
}
But these functions (which are inside of MoveNode() should be called in one transaction.
Is there a way to "merge" functions in Go? Or what is the way to solve this problem (except copy & paste code from 2 functions to the third)?
p.s The idea is simple: you have two functions which do some SQL queries and you need to do these queries in one transaction (or call 2 functions in one transaction)
The better way to go about this here will be to move tx.Commit() outside the query execution functions (DeleteNode() and CreateNode() here)
Suggested Solution :
func MoveNode() error {
tx, err := db.Begin()
// err handling
res, err := DeleteNode(tx)
// err handling
res, err := CreateNode(tx)
// err handling
tx.Commit()
}
func DeleteNode(transactionFromDbBegin) (responseFromExec, errorFromExec) {
//...
}
func CreateNode(transactionFromDbBegin) (responseFromExec, errorFromExec) {
//...
}
This should do the trick.

Coffescript Nested Do Loop / Async Nested Loop

I want to save into two collections in my mongoDB. This operations are async so I use for and do in coffee.
for machine in machines
do(machine) ->
//if machine does not exist
for part in machine.parts
do(part) ->
//if not part not exists --> save
//push part to machine parts list
//save machine
The machine parts are empty later in the db. How can I make the first do loop wait for the second do loop to finish?
EDIT Real Code Example:
recipeModel = require('../models/recipe.model')
ingredientModel = require('../models/ingredient.model')
#Save Recipe into the database
async.map recipes, (recipe, next) ->
recipeDBObject = new recipeModel()
recipeDBObject.href = recipe.href
recipeDBObject.ingredients = []
recipeModel.find({ href: recipe.href }, (err, recipeFound) ->
return next err if err
return next null, recipeFound if recipeFound.length > 0
recipeDBObject.title = recipe.title
ingredientsPushArray = []
console.log recipe.href
async.map recipe.zutaten, (ingredient, cb) ->
#Save all ingredients
ingredient.idName = ingredient.name.replace(/[^a-zA-Z0-9]+/gi, "").toLowerCase()
ingredientModel.find({ idName: ingredient.idName }, (err, ingredientFound) ->
return next err if err
if ingredientFound.length >0
ingredientDBObject = ingredientFound[0]
else
ingredientDBObject = new ingredientModel()
ingredientDBObject.name = ingredient.name
ingredientDBObject.save()
recipeDBObject.ingredients.push({"idName":ingredient.idName, "name":ingredient.name, "amount":ingredient.amount})
return cb(null, true)
)
recipeDBObject.ingredients = ingredientsPushArray
recipeDBObject.save()
return next(null, true)
)
I still don't get it working. Recipes are saved, node builds the ingredients array but it neither saves the ingredients nor does it save the array into the recipes.
EDIT 2:
async.map recipes,
(recipe, next) ->
recipeDBObject = new recipeModel()
recipeDBObject.href = recipe.href
recipeDBObject.ingredients = []
recipeModel.find({ href: recipe.href }, (err, recipeFound) ->
return next err if err
return next null, recipeFound if recipeFound.length > 0
recipeDBObject.title = recipe.title
ingredientsPushArray = []
ingredientsArray = []
async.map recipe.zutaten,
(ingredient, cb) ->
#Save all ingredients
ingredient.idName = ingredient.name.replace(/[^a-zA-Z0-9]+/gi, "").toLowerCase()
ingredientModel.find({ idName: ingredient.idName }, (err, ingredientFound) ->
return next err if err
ingredientsArray.push({"idName":ingredient.idName, "name":ingredient.name, "amount":ingredient.amount})
if ingredientFound.length >0
return cb(null, true)
else
ingredientDBObject = new ingredientModel()
ingredientDBObject.name = ingredient.name
ingredientDBObject.idName = ingredient.idName
ingredientDBObject.save((err) ->
#console.log "some erros because required is empty" if err
return cb err if err
#console.log "ingredient saved"
return cb(null, true)
)
(err, ingredientsArray) ->
console.log "This is never logged"
return err if err
recipeDBObject.ingredients = ingredientsArray
recipeDBObject.save((err)->
return err if err
return next(null, true)
)
)
)
(err) ->
console.log "show me the errors: ", err if err
Now the ingredients are saved but the recipes aren't.
Interesting ressources:
http://www.hacksparrow.com/managing-nested-asynchronous-callbacks-in-node-js.html
The easiest way is to use some module for for managing asynchronous control flow, for example
async
promise-based solutions (e.g. when, bluebird, Q)
co for ES6 generator-based control flow
Here are some simple examples.
Using async.map
async = require 'async'
async.map machines,
(machine, next) ->
# Process single machine object
Machine.findById machine._id, (err, found) ->
return next err if err # return error immediately
return next null, found if found # return the object we found
async.map machine.parts,
(part, cb) ->
# Save part to DB and call cb callback afterward
Part.create part, cb
(err, parts) ->
return next err if err # propagate error to the next handler
# All parts have been saved successfully
machine.parts = parts
# Save machine to DB and call next callback afterward
Machine.create machine, next
(err, machines) ->
if err
# Something went wrong
else
# All machine objects have been processed successfully
Using promises and when module
When = require 'when'
machines_to_save = When.filter machines, ({_id}) ->
Machine.findById(_id).then (found) -> not found
When.map machines_to_save, (machine) ->
When.map machine.parts, (part) ->
Part.create part
.then (parts) ->
machine.parts = parts
Machine.create machine
.then (saved_machines) ->
# All machines are saved
.otherwice (err) ->
# Something went wrong

CoffeeScript declare and use global funcitons

Folks, given the following code... how would one re-use the returnResult and returnError functions? Is it possible to have their scope be global to all files that are required.
fs = require 'fs'
module.exports.syncJSON = (req, res)->
returnResult = (data) ->
res.send data
returnError = (data) ->
res.send data
jsonFileContents = fs.readFileSync('sample.json', 'utf8')
returnResult(jsonFileContents)
module.exports.asyncJSON = (req, res)->
fs.readFile 'sample.json', (err, data) ->
if err
returnError(err)
else
returnResult(data.toString())
returnResult = (data) ->
res.send data
returnError = (data) ->
res.send data
I think what you're asking about is how to use returnError and returnResult in both of the exports (.asyncJSON and .syncJSON). Globals are generally a bad idea. What if someone else overwrites your global? You'll have a weird and intermittent failure. If so, all you need to do is move them outside their current scope and pass in the response object:
s = require 'fs'
returnResult = (res, data)->
res.send data
returnError = (res, err) ->
res.send err
module.exports.syncJSON = (req, res)->
jsonFileContents = fs.readFileSync('sample.json', 'utf8')
returnResult(res, jsonFileContents)
module.exports.asyncJSON = (req, res)->
fs.readFile 'sample.json', (err, data) ->
if err
returnError(res, err)
else
returnResult(res, data.toString())