I am beginner at node and firebase and I don't get how to get the right value for the output here.
In the console i get the right value but the return value is undifiend.
function Emoji() {
var ref = firebase.database().ref('users').child('9ifrkEw7YjSRGtiaFFHT1rzieDA2');
this.getEmoji = function () {
ref.once('value').then(function (snapshot) {
console.log(snapshot.val().emoji); //displays the value from database
return String(snapshot.val().emoji); //displays undefiened
});
}
}
Your return statement is actually just returning from the anonymous function that you passed to then(). It's not returning from this.getEmoji. When you call getEmoji, it's going to return immediately, and some time later your database query will generate a result. The database query is asynchronous, so you should probably make getEmoji asynchronous as well by returning a promise that's resolved with the result of your query. The caller of getEmoji can use that promise's then() method to receive the result.
Related
I have to compare few rows derived from potgres with data derived from the dynamo DB. problem is in both cases i have to iterate over data & unless i can assign the value to a variable i will have to query the same data again from either one of two databases.
function postgressdata(sql){
return new Promise(function(resolve, reject) {
client_postgres.query(sql, (err, res) => {
resolve(res);
});
});
}
let get_creatives = postgressdata(sql);
get_creatives.then(function(result) {
console.log(result); // prints the result
let new_result = result;
}
console.log(new_result) // does not print result
How Can I assign the data to a variable here & use it anywhere?
I am a newbie to NODEJS so pardon me if I am asking silly question.
Nodejs is non-blocking.
so when this block of code runs
let get_creatives = postgressdata(sql);
get_creatives.then(function(result) {
console.log(result); // prints the result
let new_result = result;
}
console.log(new_result) // does not print result
what will happen is you will get nothing printed first because .then() will be called when the promise is resolved so this line
console.log(new_result) // does not print result
will be executed first which doesn't have the value yet obviously.
after that when the promise is resolved .then will be called and your value will be set.
now how to solve this?
I am assuming you're sending the value back to the callee so you can either use the async/await structure or you can use a callback, depending on how you need the value.
You can just keep a reference to the promise as your cache. A promise in JavaScript represents the result of an async operation, not the operation itself.
If you have something like:
async function runQuery() {
const result = await db.query(sql`SELECT * FROM creatives;`);
console.log('ran query');
return result;
}
const creativesPromise = runQuery();
async function useResult() {
console.log(await creativesPromise);
}
useResult();
useResult();
useResult();
even though we use the resulting list of creatives three times, "ran query" will only get logged once. Every use of the query results will need to be async, because you never know whether the query has finished running when you request the data, but the query will only be run once.
The function worke perfectly, but if I want to print the content of the user, I receive in the firebase log this info:
Function returned undefined, expected Promise or value
The function is:
exports.accountCreate = functions.auth.user().onCreate(user => {
console.log("--->"+user.data);
console.log("ok");
});
Why the user.data is not able to retrieved the informations?
Thanks
Cloud Functions run in a container in a managed environment. The environment tries to minimize how long it keeps the container running, and to be able to do so, it must know when your function is done. Normally in JavaScript code is done when the last } has executed, but this gets more complex when you also need to consider asynchronous operations. For this reason Cloud Functions expects you to inform it when the function is done, in the case of functions.auth.user().onCreate by returning a value or promise.
When you explicitly return a value, it is clear that the function is done. When you explicitly return a promise, it's clear that the function needs to remain active until the promise is resolved/rejected. When you don't return a value, it is not clear what state the function is in.
In your case the fix is simple, and you for example just return true before the final }.
exports.accountCreate = functions.auth.user().onCreate(user => {
console.log("--->"+user.data);
console.log("ok");
return true;
});
The actual value is meaningless btw, a return null would work just as well.
So I'm struggling with this a couple days and I have found a solution for this but I feel like this isn't the good one.
I currently have the following. I don't like it because I'm nesting Promises within promises. I don't know if this is fine but it doesn't look like it.
What I'm trying to accomplish with this code is first to check the cache database for a value if it is not there then I'll check the real database.
Any tips/tricks/pointers/comments on how to do this more elegantly?
var getData = function() {
var cancel = false
var cache = db.getFromCache(query)
.then((data) => {
// Check if data is up to date
if (uptodate) {
return Promise.resolve(data)
}
cancel = true
})
return cache
.then(() => {
if (cancel)
return db.getFromDatabase().then( //code)
}
}
ps: this code may or may not run I just made it quickly for this question. I can't past the real code here
When you're in a .then() handler, you can do anyone of the following:
Return a value - that value becomes the resolved value of the parent promise. So, there is no need to return Promise.resolve(value). You can just return value.
Return a promise - When you return a promise, it is chained to the parent promise and the parent promise will not resolve until this new promise resolves and the resolved value of this returned promise will become the resolved value of the parent promise.
Throw an Exception - If a .then() handler throws, that exception is automatically caught by the promise infrastructure and is turned into a rejection so throw err works similarly to return Promise.reject(err).
As such, when you're in your .then() handler, you can just check to see if the cache data is valid and, if so, just return it. Otherwise, return a new promise to get the data.
var getData = function() {
return db.getFromCache(query).then((data) => {
// Check if data is up to date
if (uptodate) {
// return cached data, will be resolved value of promise
return data;
} else {
// get data from db, return promise that will be chained
return db.getFromDatabase();
}
})
}
getData().then(...)
Your code is way more complicated than need be:
You don't need Promise.resolve(). You can just return the value.
You don't need the cancel variable at all. You can do all your work inside the first .then() handler.
You don't need the second .then() handler.
Promises support chaining, which means that a promise can return another promise, and this one can return another one, and so on.
According to MDN:
You can pass a lambda (anonymous function) to then and if it returns
a promise, an equivalent Promise will be exposed to the subsequent
then in the method chain.
When a value is simply returned from within a then lambda, it will
effectively return Promise.resolve().
This mean that in the then block, you can check if the data is up to date in the cache. If the data is fresh return it, and the value will be wrapped in a new promise. If the data is stale, you can return the call getFromDatabase(), which returns promise:
const getData = (query) => db.getFromCache(query)
.then((data) => isUpToDate(data) ? data : db.getFromDatabase(query));
getData().then(/** code **/);
Returning from a promise wraps the returned data with a new promise, so you can manipulate the data, and return it, and it will be wrapped by a promise automatically:
db.getFromDatabase().then((data) => data.map(/** some code **/)); // result will be wrapped in a promise.
I have a service which gets data from the back end which returns as a promise. Once I resolve the promise I maintain the data within the service, but I'd like to get that saved data as many times as I want as soon as it is available.
module.factory
var dataStash = {};
var service = {
getListData : getListData,
returnDataByListname: returnDataByListname
};
return service;
function getListData(listName){
//...get the data corresponding to this list
).then(setData);
function setData (data, listName){
//store the data from the resolved promise as an
//object attribute with name same as the list name
dataStash.listName = data;
}
}//end getListData
function returnDataByListname(listName){
//how best to do this??
return dataStash.listName;
}
Everything works fine but since I'm not returning the data as soon as the promise is resolved, but rather just saving it in the service, there is the issue of how soon I can call returnDataByListname. Since I don't know when the promise will be resolved and the data made available, how can I set up returnDataByListname so that it returns the data as soon as it is available after being called?
If you're primarily caching data, then returnDataByListname could return a promise:
function returnDataByListname(listName){
return promiseStash[listName] || promiseStash[listName] = getListData(listName);
}
Then callers could call returnDataByListname('foo').then(foo => console.log(foo)); repeatedly, yet getListData('foo') would only be called once.
I am working with a function that returns a value to a variable. When i console log the variable it shows what your seen in the image. i need to get access to the value so I can display it to the user how can i do this?
this is my code
function save(user)
{
var response= Restangular.all('admin').post(user).then(function (postedUser) {
return postedUser;
});
console.log(response);
return response;
}
reponse is a promise. You can't (or should not be able to) access the value of a promises directly, since the promise might not be resolved yet.
Instead, you have to pass a callback to the promise. When the promise is resolved with a value, it passes that value to all attached callbacks. In your example, the promise will eventually be resolved with value of postedUser.
The function that calls save can access the value like so:
save(...).then(function(value) {
// do something with value here
});
Learn more about promises.
Note: You can drop the .then inside the function and simplify it to
function save(user) {
return Restangular.all('admin').post(user);
}
since you are passing the identity function to .then.