0

I have Nodejs code using request library to get the authentication token from a url.

var request = require("request")

const wellish_dev_url = "https://dev.wellish.com"

function get_auth_token(){
    const  api_end_point = wellish_dev_url + "/api/v1/auth"

    var options = {
        url: api_end_point,
        headers: {"Content-Type": "application/json"},
        auth: {
            'user': 'admin',
            'pass': 'password'}
    }

    var r = request.get(options, function(error, response, body){
        if(!error && response.statusCode==200){
            var token = JSON.parse(body)
            var auth_token = token["data"][0]["accessToken"]
            // console.log(auth_token)
            return auth_token
        }
        else{
            console.log("Code : " + response.statusCode)
            console.log("error : " + error)
            console.log('body : ' + body)
        }
    })
}

// get_auth_token()
var auth_token_new = get_auth_token()
console.log(auth_token_new)  

I want to return the auth_token to be used as an argument in another function. However, it shows undefined.

I look up online to use cb, however, I have no idea how it works. I really want to return the value without using cb. Any helps?

7
  • cb simply means callback - and it works like any other callback would Commented Apr 30, 2019 at 21:11
  • Possible duplicate of Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference Commented Apr 30, 2019 at 21:12
  • Can I do it without using cb? Commented Apr 30, 2019 at 21:12
  • I suggest to return a Promise from your function, and resolve it in the inner callback, I can provide an answer with an example if that can help Commented Apr 30, 2019 at 21:16
  • @jo_va Or you could refer to the proposed duplicate since it pretty much covers every possible topic with respect to asynchronous code in JavaScript. Commented Apr 30, 2019 at 21:17

1 Answer 1

2

Your callback is only executed once the response comes back from the server. By that time, your function will already have been executed.

Since your code is asynchronous, you need a means to return the response only when you get it back from the server.

You can use a Promise for that task.

Here is an example on how to solve it in your particular case. Use the Promise constructor to return a Promise which resolves/rejects when your inner callback gets called.

Then you simply have to chain a .then() to your function call to get the token:

...

function get_auth_token() {
    const  api_end_point = ...
    const options = ...

    return new Promise((resolve, reject) => {
        var r = request.get(options, (error, response, body) => {
            if (!error && response.statusCode == 200){
                var token = JSON.parse(body)
                var auth_token = token["data"][0]["accessToken"]
                resolve(auth_token)
            } else {
                console.log("Code : " + response.statusCode)
                console.log("error : " + error)
                console.log('body : ' + body)
                reject(error)
            }
        })
    });
}

get_auth_token()
    .then(token => console.log(token))
    .catch(error => console.error(error));

You can also use await to get the value from the Promise like this, just make sure you are using await in a function marked async:

async function parent_function() {
    function get_auth_token() { ... }

    try {
        const token = await get_auth_token();
        console.log(token);
    } catch (error) {
        console.log(error);
    }
}
Sign up to request clarification or add additional context in comments.

12 Comments

I am very new to Nodejs, and I have no idea we have to use Promise and callback, I just want to return the value simply like how python does. Is there any way to return without using Promise and callback
@Akira, your callback is executed later in time, once a response comes back from the server. So the code is inherently asynchronous. Your function will be done executing before the response from the server will come, so you need a means to execute your code only once this response comes back, you can use a Promise for that.
While using both resolve and reject it would be nice to provide a line responsible for handling the second one as well, e.g: get_auth_token().then(console.log).catch(console.log) or get_auth_token().then(result => { console.log(result) }).catch(error => { console.log(error) }) they both result's are the same in this case. To avoid confusion stick to the second example (first is for OP's further research ;)).
@Akira, take a look at this question - the answer describes how can you assign results of promise / async/await using example provided by @jo_va
@Akira, I suggest you read some material on Promise. This was already explained, using .then and async/await, see my updated answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.