Search code examples
javascriptnode.jsasynchronouses6-promise

Promises resolving in wrong order


I am playing with promises and modified a script from Medium.

When I run the script it prompts for the code then displays the json data before I can input a value. I then input a value without the prompt for the script to exit.

How can I get the input before the API call works?


'use strict'

const request = require('request')
const readline = require('readline')
let userDetails

const getInput = prompt => new Promise( resolve => {
    const io = { input: process.stdin, output: process.stdout }
    const read = readline.createInterface(io)
    read.question(`${prompt}: `, data => {
        console.log(data)
        read.close()
        resolve(data)
    })
})

const getData = () => new Promise( (resolve, reject) => {
    const options = {
        url: 'https://api.github.com/users/marktyers',
        headers: {
            'User-Agent': 'request'
        }
    }
    // Do async job
    request.get(options, (err, resp, body) => {
        if (err) reject(err)
        else resolve(JSON.parse(body))
    })
})

function main() {
    const GitHubAPICall = getData()
    const getBase = getInput('input base currency')
    GitHubAPICall
        .then(result => {
            userDetails = result
            console.log('Initialized user details')
            console.log(userDetails)
        }).then(getBase)
        .catch(err => console.log(err))
}

main()

Solution

  • In your main function, you can do it like that:

    function main() {
        const GitHubAPICall = getData; // WITHOUT ()
        const getBase = getInput; // Those 2 declarations are useless, btw
    
        GitHubAPICall()
            .then(result => {
                userDetails = result
                console.log('Initialized user details')
                console.log(userDetails)
            })
            .then(() => getBase())
            .then(data => // Do something with the data returned by 'getInput')
            .catch(err => console.log(err))
    
    }