0

I initialize coin and then give it a value inside the if-statement:

const https = require('https');
var coin = ''
var options = {
  "method": "GET",
  "hostname": "rest.coinapi.io",
  "path": "/v1/exchangerate/" + coin,
  "headers": {'X-CoinAPI-Key': 'secretkey'}
};

client.on('message', msg => {
    if (msg.content === 'money') {
        msg.reply('nice');
    }
    if (msg.content === 'BTC/USD') {
        coin = msg.content;
        var request = https.request(options, function (response) {
            response.on('data', d => {
                var json = JSON.parse(d.toString())
                var value = JSON.stringify((json.rate).toPrecision(7))
                value = value.replace(/\"/g, "")
                msg.reply(coin + ": $" + value);
            });
        });
        request.end();
    }

The server connection is working because if msg.content === 'money', it properly replies with nice. If msg.content === 'BTC/USD', it does not reply.

It seems to not be changing the value of coin before it makes the https.request.

Any help is appreciated, thank you.

Zero Cool
  • 2,541
  • 2
  • 8
  • 13
  • 1
    The `path` value on the `options` is not going to be live updated by the change to the coin variable. Once the string is computed, they are no longer tied together in any way. – Taplar Sep 04 '20 at 22:02
  • You have to `options.path = 'your lead in string' + coin;` before making your request to update it. – Taplar Sep 04 '20 at 22:03
  • also `response.on('data')` does not return the complete data, it returns chunks of data that you have to accumulate then concatenate in `response.on('end')`. See: https://stackoverflow.com/q/15714499/9867451 for more info – ibrahim mahrir Sep 04 '20 at 22:05
  • `options.path = 'your lead in string' + coin;` worked, can you make that an answer I can approve – Zero Cool Sep 04 '20 at 22:07
  • @ibrahimmahrir , is that the reason for me needing to do all that parsing and stringifying? – Zero Cool Sep 04 '20 at 22:08
  • @ZeroCool `d` will not always be the complete json string so `JSON.stringify(d)` may fail as `d` will be a chunk of the whole data, it could be the whole data but not always. The request should be like this https://jsfiddle.net/67owv9ck/. First, you accumulate `data` in `on('data')` then parse it and process it in `on('end')`, also, you don't neet to use the `stringify`/regex combo, just use `toPrecision` directly like I did – ibrahim mahrir Sep 04 '20 at 22:19
  • @ibrahimmahrir this code gave me `TypeError: Cannot read property 'toPrecision' of undefined` – Zero Cool Sep 04 '20 at 22:24

1 Answers1

0

I do think that your code is async so you should wait till the request/response has finished.

If you want to send all the tokens once

const https = require('https');
let coin = ''
let options = {
  "method": "GET",
  "hostname": "rest.coinapi.io",
  "path": "/v1/exchangerate/" + coin,
  "headers": {'X-CoinAPI-Key': 'secretkey'}
};

client.on('message', async (msg) => {
    if (msg.content === 'money') {
        msg.reply('nice');
    }
    if (msg.content === 'BTC/USD') {
        coin = msg.content;
        const res = await new Promise((res, rej)=>{
            https.request(options, function (response) {
                const tokens = []
                response.on('data', d => {
                    var json = JSON.parse(d.toString())
                    var value = JSON.stringify((json.rate).toPrecision(7))
                    value = value.replace(/\"/g, "")
                    tokens.push(coin + ": $" + value)
                });
                response.on("error", (err)=>{
                    console.error(err);
                    rej(null)
                })

                response.on("end", () => {
                    res(tokens.join("\n"))
                })
            });
        })

        msg.reply(res === null ? "error" : res);

    }})

otherwise send a message everytime the data function handler is called :

const https = require('https');
let coin = ''
let options = {
  "method": "GET",
  "hostname": "rest.coinapi.io",
  "path": "/v1/exchangerate/" + coin,
  "headers": {'X-CoinAPI-Key': 'secretkey'}
};

client.on('message', async (msg) => {
    if (msg.content === 'money') {
        msg.reply('nice');
    }
    if (msg.content === 'BTC/USD') {
        coin = msg.content;
        await new Promise((res, rej)=>{
            https.request(options, function (response) {
                response.on('data', d => {
                    var json = JSON.parse(d.toString())
                    var value = JSON.stringify((json.rate).toPrecision(7))
                    value = value.replace(/\"/g, "")
        msg.reply(coin + ": $" + value);
                });
                response.on("error", (err)=>{
                    console.log(err);
                    rej()
                })

                response.on("end", ()=>{
                    res()
                })
            });
        })

    }})
    ````
justcodin
  • 857
  • 7
  • 17
  • the second solution gave me `TypeError: Cannot read property 'toPrecision' of undefined` – Zero Cool Sep 04 '20 at 22:30
  • It's normal you don't parse the result correctly ==> JSON.parse(json).rate.toPrecision(7) – justcodin Sep 04 '20 at 22:34
  • @ZeroCool https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse – justcodin Sep 04 '20 at 22:35
  • where would that line go ? because it's not working in replace of `JSON.stringify((json.rate).toPrecision(7))` – Zero Cool Sep 04 '20 at 23:11
  • for some reason, its not working at all now. I even reverted back to my old code and it just returns 'undefined' for the value, or it returns that toPrecision isn't working – Zero Cool Sep 05 '20 at 00:17