3

I have a problem getting the restaurantname from the db with node.js, it seems it has to do something with callback parameters but I can’t find the solution for my case, hopefully one of you can help me .

I have made function who gets the name of the restaurant from a database. The first console log line gives the right retvalue and the second one gives undefined, how can I write the code so that the return value is the name of the restaurant?

Kind regards, Robert

function restaurantName(id) {
  var retvalue;
  try {
    F.model('restaurant').load(id).then(function (restaurant) {
    retvalue = restaurant.Name;
    console.log('restaurantName 1(' + id + ')' + retvalue);
    })
  } catch (err) {
    retvalue = 'Error';
  }
  console.log('restaurantName 2(' + id + ')' + retvalue);
  return retvalue;
};
piotrbienias
  • 7,201
  • 1
  • 28
  • 33
user3493979
  • 33
  • 1
  • 4

1 Answers1

6

Your function getting data from database is asynchronous, so the second console.log as well as return statement are done before the database operation finishes executing. You should return the value inside .then()

function restaurantName(id) {
    var retvalue;

    return F.model('restaurant').load(id).then(function (restaurant) {
        retvalue = restaurant.Name;
        console.log('restaurantName 1(' + id + ')' + retvalue);   
        return retvalue;           
    }).catch(function(error){
        return 'Error';
    });
};

And this function will also return a promise, so you would have to call it like that

restaurantName(1).then(function(result){
    console.log(result); // result would be retValue or 'Error'
});

EDIT

Your second problem, mentioned in a comment below this answer, is also concerned with how the promises work. In this case I recommend you use Promise.all method which resolves when all of the promises passed as an argument will resolve

let promises = [];
snapshot.forEach(u => {
    let item = u.val();
    item.key = u.key;

    promises.push(restaurantName(item.restaurant).then(function(result){
        item.restaurantName = result;
        return item;
    }));
});

Promise.all(promises).then(result => {
    console.log(result); // here you get array of items 
});

What happens here is you create an array of promises that resolve with given value (which in this case is item object every time). When you pass this array to Promise.all method, it resolves to array of values that every single promise resolved to (if no error occurs of course)

piotrbienias
  • 7,201
  • 1
  • 28
  • 33
  • The original function call is: item.restaurantName = restaurantName(item.restaurant); I've replaced it with: restaurantName(item.restaurant).then(function (result) { console.log('result: ' + result); // result would be retValue or 'Error' item.restaurantName = result; }); The result of the call is Error in stead of the correct name (which is returned in the function) – user3493979 Feb 16 '17 at 18:04
  • So you have to do `restaurantName(item.restaurant).then(function(result){ item.restaurantName = result; });` – piotrbienias Feb 16 '17 at 18:05
  • There was a typo in my answer, there was `return retValue` whereas it should be `return retvalue`, maybe that's the case if you got the same code as in my answer – piotrbienias Feb 16 '17 at 18:16
  • Now the function returns the correct name and when I use it in the call it is working fine in the log(22), but before the push the variable is undefined again, do you have a solution for that? snapshot.forEach(u => { let item = u.val(); item.key = u.key; restaurantName(item.restaurant).then(function (result) { item.restaurantName = result; console.log('22 user:' + item.name + ' ' + item.restaurantName); }); console.log('24 user:' + item.name + ' ' + item.restaurantName); sorted.push(item); }); – user3493979 Feb 16 '17 at 18:31
  • It is another issue related to how the [**`promises`**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) work. You need to read about them and understand at least their basic concepts, otherwise you will constantly encounter similar problems. Also, read about **`asynchronous`** operations in javascript – piotrbienias Feb 16 '17 at 18:37
  • I'm really gone do that! is it easy to passback the item.restaurantName value? in this block? – user3493979 Feb 16 '17 at 18:49
  • You helped me a lot, is it possible that you help me with the last part? – user3493979 Feb 16 '17 at 19:15
  • I edited the answer to include solution of this problem – piotrbienias Feb 16 '17 at 20:27
  • the result now contains the correct value restaurantname, but I don't know how to handle the sort event: sorted.push(item); – user3493979 Feb 16 '17 at 21:35
  • I think there is one thing missing, right now there is no result on the page, I think it has to do with the sorted method, whereever I place it I don't get the results – user3493979 Feb 16 '17 at 21:51
  • Right now, the sort function outside the promises doesn't have the restaurantname information, where do I have to place the call: sorted.push(item); – user3493979 Feb 17 '17 at 12:42