1

I'm having some issues getting a custom promise to work with my little app I'm working on.

Here is an abbreviated version of my app.js

var Promise = require('promise');
var Commands = require('./commands');

var respond = function() {
    var messageToRespondWith = command[0].response;
    if(typeof(command[0].response) == "function"){
        console.log('is function');
        command[0].response().then(console.log('finished'));
    }
    var response = template(messageToRespondWith, {user: user, channel: channel, message: message});
    client.say(channel, response);
};

And the commands look something like this

var config = require('./config');
var Promise = require('promise');

module.exports = [
  {
    trigger: "!random",
    response: function(){
      var unirest = require('unirest');
      var promise = new Promise(function(resolve, reject) {
      unirest.post("https://andruxnet-random-famous-quotes.p.mashape.com/cat=movies")
      .header("X-Mashape-Key", config.mashapeKey)
      .header("Content-Type", "application/x-www-form-urlencoded")
      .header("Accept", "application/json")
      .end(function (result) {
        console.log(result.status);
        // Handle errors
        if(result.status != 200){
          return promise.reject(result.body);
        }else{
          var json = JSON.parse(result.body);
          return promise.resolve(json.quote);
        }
      });
    });
  },
  permission: null
  },
]

The app.js code checks to see if the returned value type is a function, and if it is it executes it and is supposed to save that to a variable and pass that along to the next function.

I need to use a promise because obviously the bottom function call client.say() will not wait for the returned value form the API call of the function from the commands.js file.

When I try to execute this code, in my terminal I get this error...

TypeError: Cannot read property 'then' of undefined
at respond (/***/app.js:39:28)

So I'm not really sure why this is happening, I'm still learning node and the best ways to do things so maybe I'm on the wrong track here altogether.

Basic functionality

This is a twitch IRC chat bot that will read commands being typed in and respond in chat with a predetermined message. In some cases I will want to do some sort of function before spitting out the message. This is one of those cases. You can see my full app.js code here I didn't want to paste the entire thing because it's long and include parts that I thought were not relevant here.

Jordan
  • 2,393
  • 4
  • 30
  • 60
  • 1
    1) You didn't post the code where you are actually calling `respond` , 2) in your `respond` function `command[0]` appears to very clearly be undefined. Did you mean to pass that as an argument? – azium Jul 17 '15 at 20:11
  • Oh I see you I think you mean to say `var command = require('./commands')` – azium Jul 17 '15 at 20:14
  • Here is the full repo minus the commands and config files if you want to see the full code, I don't want to post here because I don't think it's relevant, but it may be. https://github.com/Jordan4jc/super-fly-twitch-bot – Jordan Jul 17 '15 at 20:16
  • 3) What is the point of this line `var messageToRespondWith = command[0].response;` 4) Your `then()` function doesn't seem to be doing anything. – azium Jul 17 '15 at 20:16
  • That line probably should be moved into an else attached to the typeof check because if the type of the response is not a function, meaning it's just a string, then it will just send the string. – Jordan Jul 17 '15 at 20:18
  • Sorry, I'm a bit confused. Will come back to this later. – azium Jul 17 '15 at 20:21
  • I'll update shortly with a short description of the project scope. – Jordan Jul 17 '15 at 20:24

2 Answers2

2

You need to return the promise at the end of this function. by default your function returns "undefined", thus the error. You need return the promise synchronously and then later you will asynchronously resolve it.

In your end callback, you are returning promise.resolve(..) but this is not correct. You need to call promise.resolve(..) but do not need to return it.

   response: function(){
      var unirest = require('unirest');
      var promise = new Promise(function(resolve, reject) {
      unirest.post("https://andruxnet-random-famous-quotes.p.mashape.com/cat=movies")
      .header("X-Mashape-Key", config.mashapeKey)
      .header("Content-Type", "application/x-www-form-urlencoded")
      .header("Accept", "application/json")
      .end(function (result) {
        console.log(result.status);
        // Handle errors
        if(result.status != 200){
          promise.reject(result.body);
        }else{
          var json = JSON.parse(result.body);
          promise.resolve(json.quote);
        }
      });
      return promise;
    });
Robert Levy
  • 28,747
  • 6
  • 62
  • 94
  • This is still giving me the same result unfortunately. – Jordan Jul 17 '15 at 20:24
  • @Jordan did you change `var Commands = require..` to `var command` ? `command[0].whatever` doesn't exist in your scope in your current code. – azium Jul 17 '15 at 20:25
  • the `command[0].whatever` is coming from another function outside of this scope, I included a link to the full `app.js` file on github so you can see, I didn't want to include it because I was afraid it was too long and didn't need to be presented for the problem at hand. – Jordan Jul 17 '15 at 23:23
  • 1
    If you use a debugger, you should see that `promise.reject` and `promise.resolve` don't exist. You need to just use `reject` and `resolve`. – Macil Jul 17 '15 at 23:42
  • Thank you, your answer wasn't quite there but helped me get to the correct answer, I added it below yours. – Jordan Jul 18 '15 at 12:49
1

Robert's answer helped me get to the final working answer. I do need to return the result, but even after trying to return the promise variable and changing reject and resolve to remove the promise part before them (as mentioned in the comments to his answer) I removed the promise variable all together and returned the entire promise itself like so

response: function(){
  var unirest = require('unirest');
  return new Promise(function(resolve, reject) {
    unirest.post("https://andruxnet-random-famous-quotes.p.mashape.com/cat=movies")
    .header("X-Mashape-Key", config.mashapeKey)
    .header("Content-Type", "application/x-www-form-urlencoded")
    .header("Accept", "application/json")
    .end(function (result) {
      console.log(result.status);
      // Handle errors
      if(result.status != 200){
        reject(result.body);
      }else{
        var json = JSON.parse(result.body);
        resolve(json.quote);
      }
    });
  });
},
Jordan
  • 2,393
  • 4
  • 30
  • 60