1

Im learning Javascript and im up to a section on Promises. So decided to try and convert some of my earlier projects to use Promises. But I cant get my head around it. Iv read a lot of guides and browsed through this site but I still cant understand why this isnt working.

This the function im working with, trying to do a database call that returns a promise, that can then be logged or whatever.

const getID = function (product) {
  let query = `select typeID from invTypes where UPPER(typeName) =UPPER('${product}')`;
  return new Promise((resolve, reject) => {
    resolve(
      DB.get(query, function (err, result) {
        if (err) {
          Bot.say(`Error looking up ${product}`);
        } else {
          console.log(result.typeID); //587
          return result.typeID;
        }
      })
    );
  });
};

getID(product).then((data) => console.log(data)); //Database {}

The console outputs

Database {}
587

so the .then(data => console.log(data)) //Database {} Is still happening before the promise is returned,

as you can see the other log from earlier up inside the function is actually logging after it.

Can someone help me with this iv been at this one function for hours now haha. I think I have some kind of fundamental misunderstanding that Im not picking up on from my bootcamp videos or anything im reading.

AlecJeay
  • 35
  • 4
  • Why not just get a version of your database that has promise support built-in? If you're using mysql, that would be `mysql2/promise`. – jfriend00 Jan 27 '22 at 05:52
  • Thanks but that doesn thelp me understand why this isnt working. – AlecJeay Jan 27 '22 at 05:56
  • Well, this is wrong in a several ways and it looks like you don't understand the basics of wrapping asynchronous operations in a promise. My suggestion was rather than promisifying things yourself, why not use built-in promise support? That's always the preferred solution when available. Why reinvent a wheel someone else has already invented and offered you for free? – jfriend00 Jan 27 '22 at 05:58
  • Sorry if i was blunt, Iv literally been at this one function for hours. But I have several other ones Id like to work on refactoring to use promises. because at the moment I just use setTimeouts to wait and hope a callback is ready. – AlecJeay Jan 27 '22 at 06:05
  • Also, with ES6 you can usually use `async` and `await` so you don't have to write explicit promises. – Barmar Jan 27 '22 at 06:18
  • So, what database are you using? Is it mysql? If so, please switch to `mysql2` and then load `mysql2/promise` as explained in the [doc](https://www.npmjs.com/package/mysql2#using-promise-wrapper). Then, you can use built-in promise support. This is the best way to solve this problem. – jfriend00 Jan 27 '22 at 06:19
  • Hi @Barmar I did try to do it with async / await but I couldnt get that to work either. No matter what i try it never seems to wait for my database call to come back before it moves on. – AlecJeay Jan 27 '22 at 06:20
  • Im using sqlite3. Im lookin gnow I see there is an sqlite3 promised version, Ill look into it. – AlecJeay Jan 27 '22 at 06:20
  • @AlanSunshineSnape - YOU need promise support before you can use `await`. – jfriend00 Jan 27 '22 at 06:21
  • 1
    The basic problem in your code is that you should be calling `resolve` in the `DB.get()` callback function, not around the call to `DB.get()`. – Barmar Jan 27 '22 at 06:23
  • 1
    `return result.typeID` should be `resolve(result.typeID)` – Barmar Jan 27 '22 at 06:23

1 Answers1

3

In promise code, you use resolve() in the asynchronous function's callback function to return values.

const getID = function(product) {
  let query = `select typeID from invTypes where UPPER(typeName) =UPPER('${product}')`;
  return new Promise((resolve, reject) => {
    DB.get(query, function(err, result) {
      if (err) {
        Bot.say(`Error looking up ${product}`);
        reject(`Error looking up ${product}`);
      } else {
        console.log(result.typeID); //587
        resolve(result.typeID);
      }
    })
  });
};
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • @AlanSunshineSnape - But ... you presumably have many other places where you will use your database and thus it would be better to get the version of your database that already supports promises so you're not manually promisifying things every time you want to use your database in this way. That's why I don't recommend this solution. – jfriend00 Jan 27 '22 at 06:39