Return in pg-promise - node.js

I created a separate file with all my queries using pg-promise module for Node. While for most of them I just use req, res after a query, for one I want to return a value back. It does not work. It returns undefined.
passportLogin: (email)=> {
db.one(`SELECT userid
FROM user`)
.then( result => {
return result;
})
.catch( error => {
return error;
});
}

That code has two problems at the same time:
invalid promise use, when inside .catch you do return result, that's not how promise rejects are handled, you must either provide the error handling, or re-throw / re-reject the error.
invalid use of pg-promise library. You use method one that's supposed to reject when anything other than 1 record is returned, as per the method's documentation, and at the same time you are saying I need to catch if it returns more than one row... , which is a logical contradiction.
The result of it is as follows: your query executes successfully, and returns more than one record, which in turn makes method one reject, and then you take the rejection reason and turn it into a resolved one by doing return result. In all, your code is broken all over the place.
First, with pg-promise you are supposed to use the right method, according to the number of records you are expecting back, see The Basics.
And then handle .then/.catch according to your business logic. I can't be more specific here, because you did not provide further details on this.

Related

What Is the Proper Way to define resolve/reject in async applications

I am trying to build a financial system in NodeJS. I am refactoring my code from using callbacks to using Promises to minimize nesting. But I am struggling with understanding what would the proper meaning of a Resolve or a Rejection should be. Let's say in a situation where I am checking the balance before debiting an account, would the result where the balance is insufficient be a resolve or a reject? Does Resolve/Reject pertain to success or failure of code execution or that of the logical process?
There is lots of design flexibility for what you decide is a resolved promise and what is a rejected promise so there is no precise answer to that for all situations. It often takes some code design judgement to decide what best fits your situataion. Here are some thoughts:
If there's a true error and any sequence of operations of which this is one should be stopped, then it's clear you want a rejection. For example, if you're making a database query and can't even connect to the database, you would clearly reject.
If there's no actual error, but a query doesn't find a match, then that would typically not be a rejection, but rather a null or empty sort of resolve. The query found an empty set of results.
Now, to your question about debiting an account. I would think this would generally be an error. For concurrency reasons, you shouldn't have separate functions that check the balance and then separately debit it. You need an atomic database operation that attempts to debit and will succeed or fail based on the current balance. So, if the operation is to debit the account by X amount and that does not succeed, I would think you would probably reject. The reason I'd select that design option is that if debiting the account is one of several operations that are part of some larger operation, then you want a chain of operations to be stopped when the debit fails. If you don't reject, then everyone who calls this asynchronous debit function will have to have separate "did it really succeed" test code which doesn't seem proper here. It should reject with a specific error that allows the caller to see exactly why it rejected.
Let's say in a situation where I am checking the balance before debiting an account, would the result where the balance is insufficient be a resolve or a reject?
There's room to go either way, but as I said above, I'd probably make it a reject because if this was part of a sequence of operations (debit account, then place order, send copy of order to user), I'd want the code flow to take a different path if this failed and that's easiest to code with a rejection.
In general, you want the successful path through your code to be able to be coded like this (if possible):
try {
await op1();
await op2();
await opt3();
} catch(e) {
// handle errors here
}
And, not something like:
try {
let val = await op1();
if (val === "success") {
await op2();
....
} else {
// some other error here
}
} catch(e) {
// handle some errors here
}
Does Resolve/Reject pertain to success or failure of code execution or that of the logical process?
There is no black and white here. Ultimately, it's success or failure of the intended operation of the function and interpreting that is up to you. For example, fetch() in the browser resolves if any response is received from the server, even if it is a 404 or 500. The designers of fetch() decided that it would only reject if the underlying networking operation failed to reach the server and they would leave the interpretation of individual status codes to the calling application. But, often times, our applications want 4xx and 5xx statuses to be rejections (an unsuccessful operation). So, I sometimes use a wrapper around fetch that converts those statuses to rejections. So, hopefully you can see, it's really up to the designer of the code to decide which is most useful.
If you had a function called debitAccount(), it would make sense to me that it would be considered to have failed if there are insufficient funds in the account and thus that function would reject. But, if you had a function called checkBalance() that checks to see if a particular balance is present or not, then that would resolve true or false and only actual database errors would be rejections.
To use resolve or reject depends on your implementation.
Basic Promise upgrade from callback:
return new Promise(function (resolve, reject) {
myFunction(param, function callback(err, data) {
if (err)
reject(err);
else
resolve(data);
})
})
and shortcut to this is util.promisify(myFunction)
const util = require('util');
function myFunction(param, callback) { ... }
myFunctionAsync = util.promisify(myFunction)
myFunctionAsync(param).then(actionSuccess).catch(actionFailure)
As you see, reject is used to pass the error, and resolve to pass the result.
You can use with resolve/reject:
function finacialOperationAsync() {
return new Promise((resolve, reject) => {
const balance = checkBalance();
if (balance < 0)
reject(new Error('Not enough balance'))
else
finacialOperation((err, res) => {
if (err)
reject(err);
then
resolve(res);
});
})
}
finacialOperationAsync().then(actionOnSuccess).catch(actionOnFailure)
Or you can use true/false and async/await:
function checkBalanceAsync() {
return new Promise(resolve => {
resolve(checkBalance() >= 0);
})
}
async function finacialOperationAsync() {
if (await checkBalanceAsync()) {
const res = await finacialOperationAsync();
return actionOnSuccess(res);
} else
return actionFailure();
}
All err variables in the callback style code should be mapped to rejection in promises. In this way, promisify decorator converts callbacks to promises, so you should take this approach to maintain parity.

What does two return statements for javascript promise mean here?

i am learning javascript and Node.js and came across this code. I have a user.js representing user schema and server.js that contains my post route.
UserSchema.methods.generateAuthToken = function() {
return user.save().then(()=> { //Return Statement 2
return token; //Return Statement 3
});
};
I want to understand what two return statements mean when user.save() is called and in 'then' we return a token. Why do we need 'return' ahead of 'user.save()'
Here's the 'POST route'
user.save().then(()=>{
return user.generateAuthToken(); //Return Statement 1
}).then((token) =>{
res.header('x-auth', token).send(user);
})
Why do we return 'user.generateAuthToken()' instead of just calling it ? Why are we using three return statements whereas according to my understanding no return statement is required as a promises automatically return something in the 'then' block.
Could someone please explain the flow here ? I would be very thankful to you.
Thanks.
You my friend are working with Promises..
(1st code)
when you call
user.save()
you are returning a Promise..the function may or may not end successfully..Promises have a
Promise.prototype.then
function..the first arg is a success function to be called when the function resolves(the real term)
In 2nd code..inside that 1st function you returned another Promise that's it(the whole then returns another Promise..but only if it resolves)
If you need to beat the crap out of JavaScript try googling Eloquent JavaScript (by Marijn Haverbecke)
Why do we need to 'return' ahead of 'user.save()'
This returns the promise that resolves the token. Without the return we'd have no way of accessing the token outside of the save function.
Why do we return 'user.generateAuthToken()' instead of just calling it?
Again, we need the token. If we just call the function, the save is performed but we don't have the token when the promise resolves (in this case it's used for the header of the response).
Why are we using three return statements whereas according to my understanding no return statement is required as a promises automatically return something in the 'then' block.
Your understanding is wrong. Whatever is returned from the promise is available to then, if nothing is returned, there is no parameter (in this case the token).
In the first function, user.save() will return a promise, and as you are returning the token in the then block of user.save(), promise will resolve the value of token.
In the second function if you haven't used return ahead of user.generateAuthToken();, it will just execute that function and you will be getting the results of user.save() in the then block.

Using Node.Js and Promises, how do you return a fulfilled promise? [duplicate]

This question already has answers here:
MongoDB atomic "findOrCreate": findOne, insert if nonexistent, but do not update
(4 answers)
Mongoose - Create document if not exists, otherwise, update- return document in either case
(5 answers)
Closed 4 years ago.
I am using Mongoose and am in a situation in which I am looking up a customer from the database. If the customer exists, I will return a customerId. However, if the customer does not exist, I want to create them and then return the customer id. In either case, I want the promise to end with a customerID. Anyway, while I have seen in the documentation that is possible to instantly wrap a return value using "Promise.resolve", I am receiving an error. This feature is apparently useful when trying to make synchronous tasks more congruent with Node by wrapping their return values. Anyway, what is a better way to deal with this or return a promise? At the end of the day I want the code to return the customer object or fall through to a catch/error.
TypeError: Promise.resolve is not a constructor
Below is the code (I edited out some security things, but I think I didn't make any serious alterations).
Customer.findOne({email: email}).then((customer) => {
if (customer) {
return Promise.resolve(customer);
}
else {
return new Customer({email: email}).save();
}
}).then( function(customer) {...
This is really about Promises, not Mongoose or MongoDb. If you are in a situation in which you are inside of a promise and want to return a value to the chain, what do you do?
You don't need Promise.resolve() here. If a then handler returns a non-promise, the promise returned by the then call will resolve with that value. In other words, it will already be wrapped, so wrapping it again is redundant.
On an unrelated note, the else is also redundant, as return statements exit the currently executing function:
Customer.findOne({email: email}).then((customer) => {
if (customer) {
return customer;
}
return new Customer({email: email}).save();
}).then( function(customer) {...
Promise.resolve() and Promise.reject() are generally intended for operations that have special cases where no actual asynchronous operation takes place, but you'd still like them to return promises in those cases for consistency's sake.
As a trivial example, imagine I have a bunch of objects with uid properties that may or may not have a corresponding username property. I want to make sure all of them have a username property, so I write a function I can call on all of them, which will look up the username from a database if it is missing. For consistency I want this function to always return a promise, even if the username is already there and no lookup is actually necessary. Also, I can add a case where, in the event that the uid is missing, the promise will reject without wasting time trying to look up undefined as a uid.
Could look something like this:
function ensureUsername(user) {
if ('username' in user) return Promise.resolve(user);
return lookUpUsernameByUid(user.uid)
.then((username) => {
user.username = username;
return user;
});
}
Promise.resolve() is also quite useful when dealing with values that may or may not be promises. This is because it simply returns the value if it already is a promise.
Let's say you want to write a function foo that invokes some callback function. The callback function may or may not be asynchronous-- i.e. it may return a promise, but is not required to. How do you accomplish this?
It's simple. Just put the result of the callback in Promise.resolve and chain a then onto it:
function foo(cb) {
return Promise.resolve(cb())
.then((callbackResult) => {
// Do whatever...
});
}
This will work whether cb returns a promise that resolves with callbackResult or simply returns callbackResult directly.

Wrapping/intercepting a promise in an inner function

I'm having difficulty finding an answer to my question, perhaps because I don't know how to ask it (what search terms to use). I'm really struggling to understand promises, and have watched a number of tutorial videos and am still not getting some fundamental piece to make it click.
In Node, I am using the request-promise module, which returns a promise when I make a call to an rp() method. I am calling
return rp(service);
from within a function. But what I want to do, instead, is add a .then() handler to this to do some post-processing with the result of the service call, BEFORE returning the promise back to the caller so the caller can still have its own then handler.
How do I accomplish this?
It would be helpful to see your current code to better understand where exactly you are struggling with.
In general, you can think of promises as a placeholder for some future value that you can chain together.
If I understood your question correctly, you would like to make a request to a server, receive the response, do something with the response and return it back to the caller.
const callService = (url) => {
// make sure to return your promise here
return rp(url)
.then((html) => {
// do something with html
return html;
});
};
Now you can call it like so -
callService('http://www.google.com')
.then((html) => {
console.log(html);
}).catch((err) => {
// error handling
});
The common mistake is to omit the return statement in your top level function and subsequent then functions.
Feel free to provide additional details.

Node.js: serial operations with branching

I'm new to node.js and using it for a backend that takes data from syslog messages and stores it to a database.
I've run into the following type of serial operations:
1. Query the database
2. If the query value is X do A. otherwise do B.
A. 1. Store "this" in DB
2. Query the database again
3. If the query value is Y do P. otherwise do Q.
P. Store "something"
Q. Store "something else"
B. 1. Store "that" in the DB
2. Store "the other thing" in the DB
The gist here is that I have some operations that need to happen in order, but there is branching logic in the order.
I end up in callback hell (I didn't know what that is when I came to Node.. I do now).
I have used the async library for things that are more straight forward - like doing things in order with async.forEachOfSeries or async.queue. But I don't think there's a way to use that if things have to happen in order but there is branching.
Is there a way to handle this that doesn't lead to callback hell?
Any sort of complicated logic like this is really, really going to benefit from using promises for every async operation, especially when you get to handling errors, but also just for structuring the logic flow.
Since you haven't provided any actual code, I will make up an example. Suppose you have two core async operations that both return a promise: query(...) and store(...).
Then, you could implement your above logic like this:
query(...).then(function(value) {
if (value === X) {
return store(value).then(function() {
return query(...).then(function(newValue) {
if (newValue === Y) {
return store("something");
} else {
return store("something else");
}
})
});
} else {
return store("that").then(function() {
return store("the other thing");
});
}
}).then(function() {
// everything succeeded here
}, function(err) {
// error occurred in anyone of the async operations
});
I won't pretend this is simple. Implemented logic flow among seven different async operation is just going to be a bit of code no matter how you do it. But, promises can make it less painful than otherwise and massively easier to make robust error handling work and to interface this with other async operations.
The main keys of promises used here are:
Make all your async operations returning promises that resolve with the value or reject with the failure as the reason.
Then, you can attach a .then() handler to any promise to see when the async operation is finished successfully or with error.
The first callback to .then() is the success handler, the second callback is the error handler.
If you return a promise from within a .then() handler, then that promise gets "chained" to the previous one so all success and error state becomes linked and gets returned back to the original promise state. That's why you see the above code always returning the nested promises. This automates the returning of errors all the way back to the caller and allows you to return a value all the way back to the caller, even from deeply nested promises.
If any promise in the above code rejects, then it will stop that chain of promises up until an actual reject handler is found and propagate that error back to that reject handler. Since the only reject handler in the above code is at the to level, then all errors can be caught and seen there, no matter how deep into the nested async mess it occurred (try doing that reliably with plain callbacks - it's quite difficult).
Native Promises
Node.js has promises built in now so you can use native promises for this. But, the promise specification that node.js implements is not particularly feature rich so many folks use a promise library (I use Bluebird for all my node.js development) to get additional features. One of the more prominent features is the ability to "promisify" an existing non-promise API. This allows you to take a function that works only with a callback and create a new function that works via a promise. I find this particularly useful since many APIs that have been around awhile do not natively return promises.
Promisifying a Non-Promise Interface
Suppose you had an async operation that used a traditional callback and you wanted to "promisify it". Here's an example of how you could do that manually. Suppose you had db.query(whatToSearchFor, callback). You can manually promisify it like this:
function queryAsync(whatToSearchFor) {
return new Promise(function(resolve, reject) {
db.query(whatToSearchFor, function(err, data) {
if (!err) {
reject(err);
} else {
resolve(data);
}
});
});
}
Then, you can just call queryAsync(whatToSearchFor) and use the returned promise.
queryAsync("foo").then(function(data) {
// data here
}, function(err) {
// error here
});
Or, if you use something like the Bluebird promise library, it has a single function for promisifying any async function that communicates its result via a node.js-style callback passed as the last argument:
var queryAsync = Promise.promisify(db.query, db);

Resources