-1

I have read the following stack overflow post and this one, but i still can't find the solution to my problem.

I have function defined in a utility.js file as follows:

let geocodeOptions = {
    provider: 'google',
    httpAdapter: 'https',
    apiKey: 'GMAPKEY_HERE',
    formatter: null
};
async function postInformation(message, bot) {
    try {
        let messageContent = message.content;        
        let EncId = await getDetails(messageContent), msg

const NodeGeocoder = require('node-geocoder');

geocoder = NodeGeocoder(geocodeOptions);
        geocoder.reverse({ lat: EncId[0], lon: EncId[1] }).then(res => {
            msg = "*" + res[0]['city'] + "*";
        })

        let post;

        let delayValue = await Bluebird.delay(2000)
        if (delayValue) {
            post = getMsg1() + '\n' + getMsg2() + '\n' + EncId;
            return await post
        }

    } catch (error) {
        console.log(error)
    }
}

And in the main file, I am calling it as follows:

const util = require('./utility')
util.postInformation(message, client).then(value => {
     console.log("value from main file")
     console.log(value) // Always prints undefined
})

I also tried following:

let value = await util.postInformation(message, client);
console.log("value from main file")
console.log(value) // Always prints undefined

Instead of redirecting to other posts, pls provide a solution to this problem, where is the mistake i am making here.

  • erm `return await post` ? no ... just `return post` (I assume that `getMsg1` and `getMsg2` are synchronous) – Jaromanda X Mar 02 '18 at 04:48
  • 1
    reading the **[documentation for Bluebird.delay](http://bluebirdjs.com/docs/api/promise.delay.html)** ... *Returns a promise that will be resolved with value (or undefined) after given ms milliseconds)* - well, since you haven't passed IN a value for `.delay` it actually **does** resolve as undefined - hence, your `if` is always **false** – Jaromanda X Mar 02 '18 at 04:51
  • @JaromandaX I have specified delay, `2000`, yes they are synchronous –  Mar 02 '18 at 05:07
  • yes, you've specified delay, but no second argument ... therefore, delayValue will always be `undefined` - it says so, right there in the documentation ... why the 2 second delay? what do you think `delayValue` could possibly be? true or false? what makes it true? what makes it false? – Jaromanda X Mar 02 '18 at 05:10
  • Or, more simply .. what is the purpose of the 2 second delay? – Jaromanda X Mar 02 '18 at 05:11
  • Actually i am running a geocoder function before that, which takes 2 secs to complete, i tried async await on that as well, but it would return undefined...so i manually chose to add delay –  Mar 02 '18 at 05:21
  • well ... if it doesn't return a promise, then, no you can't `await` it ... but you can `promisify` it, and have neater code that doesn't rely on "delay" hacks - if you showed the code I could help with that too – Jaromanda X Mar 02 '18 at 05:31
  • Sure, updated the code @JaromandaX –  Mar 02 '18 at 05:53
  • oh ... Geocoder DOES return a promise ... you just need to `await` it .. **AND** return `msg` if you want to use msg – Jaromanda X Mar 02 '18 at 05:54
  • Yes, I actually tried it out, Its working fine wo any explicit delays.. Thanks –  Mar 02 '18 at 05:58
  • Here's how I'd probably write your code - https://jsfiddle.net/4hoak9u9/ – Jaromanda X Mar 02 '18 at 05:59

1 Answers1

-1

I'm just going to leave this here for now

const NodeGeocoder = require('node-geocoder');

let geocodeOptions = {
    provider: 'google',
    httpAdapter: 'https',
    apiKey: 'GMAPKEY_HERE',
    formatter: null
};
async function postInformation(message, bot) {
    try {
        let messageContent = message.content;
        let [lat, lon] = await getDetails(messageContent);

        geocoder = NodeGeocoder(geocodeOptions);
        let msg = await geocoder.reverse({lat, lon})
        .then(([res]) => "*" + res.city + "*")

        return getMsg1() + '\n' + getMsg2() + '\n' + EncId;
    } catch (error) {
        console.log(error)
    }
}

OK - let me explain some (relevant) changes to your code

As NodeGeocoder returns a Promise, we can await, however, you need to return something in the .then, otherwise you get undefined

awaiting geocoder.reverse means no need for the (hacky) pause for 2 seconds, so, that's gone. Besides

let x = await Bluebird.delay(2000)

will always result in x being undefined - you'd want

let x = await Bluebird.delay(2000, true)

at least, if you want x to be truthy - but since it's just a delay, there's really no reason for testing the result of Bluebird.delay - because we already know it


The not so relevant changes:

I made a few little (ES2015+) changes, like shorthand arrow notation, and ([res]) => res.city instead of res => res[0]['city'] just to make the code neater

Also

let [lat, lon] = await getDetails(messageContent);

instead of

let EncId = await getDetails(messageContent)

and accessing lat as EndId[0] and lon as EndId[1] - also means

{ lat: EncId[0], lon: EncId[1] }

is just

{ lat, lon }
Jaromanda X
  • 47,382
  • 4
  • 58
  • 76
  • Not sure why this was downvoted, perhaps the lack of explanatio - was literally out the door when I posted the answer, "the real world"™ needed my attention for a couple of hours – Jaromanda X Mar 02 '18 at 08:05