-2

I'm trying to get data from an API, but it somehow gets weird data, I've tried many things and i don't know what else I could do.

const https = require("https");
https.get(`https://drednot.io/api/scoreboard?count=1000&offset_score=-1`, (resp) => {
    let data = '';
    resp.on('data', (chunk) => {
        data += chunk;
    });
    resp.on('end', async () => {
        try {
            //console.log(data)
            let result = JSON.parse(data.toString())["ships"];
            console.log(result)
        } catch (err) {
            console.log("Error: " + err.message);
        }
    });
}).on("error", async (err) => {
    console.log("Error: " + err.message);
});

both the raw data and the parsed data have some weird things inside them, for example, a substring in the raw data

{"sh         ip_name":"⚜️ Full Farm Barn","hex_code":"20DE1","color":9079434,"score":2395790}

or a part in the parsed data (different because above isn't inside the parsed for some reason)

{
    ship_name: '�������� '        ,
    hex_code: '78AD5F',
    color: 815352,
    score: 25915190
}

Edit: the � characters are parsed correctly, they just cant be displayed by the terminal which isn't the problem.

Full code to see what i mean, it should sometimes print a change but it prints changes all the time which is incorrect:

const https = require("https");


function sleep(ms) {
    if (ms <= 0) {

    } else {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

var shipData = {};
class Syncer {
    finished;
    round_fetch;
    round_error;

    constructor() {
        this.finished = true;
        this.round_fetch = 0;
        this.round_error = 0;
    }

    fetch_data(offset_score, next_request, recursion_deep) {
        //console.log(offset_score)
        this.round_fetch += 1;

        https.get(`https://drednot.io/api/scoreboard?count=1000&offset_score=${offset_score.toString()}`, (resp) => {
            let chunks = [];
            resp.on('data', (chunk) => {
                chunks.push(chunk);
            });

            resp.on('end', async () => {
                let end = Date.now();
                try {
                    //console.log(data)
                    let data = Buffer.concat(chunks).toString('utf8');
                    //console.log(data)
                    console.log(`Index of hexcode: ${data.search("32FF2B")}`)
                    let result = JSON.parse(data)["ships"];
                    data = null;
                    let next_offset = result[result.length - 1].score;
                    if (next_offset === offset_score) {
                        next_offset -= 1;
                    }
                    if (next_offset < 10000000) {
                        next_offset = -1;
                    }
                    if (next_offset !== -1) {
                        if (end < next_request) {
                            await sleep(next_request - end);
                        }
                        this.fetch_data(next_offset, Date.now() + 100, recursion_deep + 1);
                    } else {
                        this.finished = true;
                    }
                    next_offset = null;
                    let rank = (recursion_deep * 1000) + 1;

                    for (let ship of result) {
                        await sleep(1);
                        ship["rank"] = rank;
                        if (ship.hex_code === "32FF2B") {
                            console.log(`Parsed ship: ${ship}`)
                        }
                        if (shipData[ship.hex_code] !== undefined) {
                            this.checkChange(shipData[ship.hex_code], ship);
                        }
                        shipData[ship.hex_code] = ship;
                    }
                    result = null;
                    offset_score = null;
                } catch (err) {
                    console.log("Error: " + err.message);
                    await sleep(1000);
                    this.round_error += 1;
                    await this.fetch_data(offset_score, Date.now() + 100, recursion_deep);
                }
            });
        }).on("error", async (err) => {
            console.log("Error: " + err.message);
            await sleep(1000);
            this.round_error += 1;
            await this.fetch_data(offset_score, Date.now() + 100, recursion_deep);
        });
    }
    checkChange(oldShip, newShip) {

        // CHECK IF OLD NAME ISNT THE SAME AS THE NEW ONE, IF SO PRINT CHANGE
        if (oldShip.ship_name !== newShip.ship_name) {
            console.log(`${oldShip.ship_name} | ${newShip.ship_name}`)
        }
    }


    async launch() {
        //this.postChanges();
        while (true) {
            try {
                if (this.finished) {
                    this.finished = false;
                    console.log(`Fetch all ships, fetch ${this.round_fetch}, error ${this.round_error}`);
                    this.round_error = 0;
                    this.round_fetch = 0;
                    await sleep(100);
                    this.fetch_data(-1, Date.now() + 100, 0);
                }
                await sleep(1000);
            } catch (e) {
                console.log(e);
            }
        }
    }
}

function launch() {
    // Start the servers
    var synchro = new Syncer();
    synchro.launch()
}

launch()
  • Does this answer your question? [Nodejs scraped content isn't properly decoded (weird question mark caracters)](https://stackoverflow.com/questions/46315308/nodejs-scraped-content-isnt-properly-decoded-weird-question-mark-caracters) – esqew Nov 18 '21 at 14:30
  • I may have to say that the result is different with each request, if you don't know what I mean use a loop and compare the results. – Gravity Assist Nov 18 '21 at 14:33
  • Your terminal doesn't support ``. That's not ASCII. My terminal supports it, but it's looks weird. `` is not `Paradise`. That are different characters. – jabaa Nov 18 '21 at 14:45
  • @jabaa Its not about the paradise, its about the spaces like here `"col or"` – Gravity Assist Nov 18 '21 at 14:48
  • I can't reproduce the spaces. – jabaa Nov 18 '21 at 14:53
  • Sorry, I don't understand. What's weird here? Can you spell it out for me? What did you expect and what did you get instead? What is "a substring in the raw data"? And can you please help me reproduce your issue? How did the spaces get there? What was the input and what was the output? – Wyck Nov 18 '21 at 14:56
  • I even replaced `console.log(result);` with `console.log(result.map((r) => r.ship_name));` and all ship names were printed. That means there are no weird characters. – jabaa Nov 18 '21 at 14:57
  • Ok @jabaa i've created a repl to show you what exactly im struggling with https://replit.com/join/udylzttyze-timohiho *the main problem is that it thinks there are changes even if there are none* – Gravity Assist Nov 18 '21 at 15:01
  • I have to create an account to see your repl and I won't do that. – jabaa Nov 18 '21 at 15:01
  • @jabaa ok yeah i can show it without you having to create a account https://replit.com/@Timohiho/Ghostcharacters#index.js use that link – Gravity Assist Nov 18 '21 at 15:03
  • What exactly was I supposed to see there? Looks correct. – jabaa Nov 18 '21 at 15:05
  • It isn't correct, all those changes `old name | new name` show that a ship changed its name which in reality isn't the case since you can only change your ship name once every 10 minutes. (I've created the same in python and in python this problem doesn't appear) – Gravity Assist Nov 18 '21 at 15:07
  • How do you expect any kind of help without [mcve]? – jabaa Nov 18 '21 at 15:08
  • Why do you think the problem is in the frontend and not in the backend? Can you compare the raw bytes? – jabaa Nov 18 '21 at 15:13
  • Added the full code so you can see what i mean. – Gravity Assist Nov 18 '21 at 15:14
  • [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/): _"StackOverflow is a question-and-answer site for specific questions about actual code; “I wrote some buggy code that I can’t fix” is not a question, it’s a story, and not even an interesting story."_ Please provide some debugging details. – jabaa Nov 18 '21 at 15:14
  • If i had an error i would show that, the fact that I'm not having any error and still have incorrect output is what I'm struggling with. – Gravity Assist Nov 18 '21 at 15:18
  • _"Please provide debugging details"_ means, read the raw data and compare the bytes. Provide a specific example. Don't expect others to debug your code and network communication for you. You could log the raw values into different files until the problem occurs and then analyze the data in the files. You should log the raw data, the parsed data and the element that differs. – jabaa Nov 18 '21 at 15:19
  • If you just run this program by running `node app.js >output.txt` and then look at output.txt in a high-quality text editor such as vscode, do you still see the same problem? (i.e. Is this just a problem with your terminal?) – Wyck Nov 18 '21 at 15:23
  • I did that, I've written the raw data into a file and looked at it, when writing to a file all those weird things disappear (even when looking at the binary data it looks correct), but since i need the data in the same process i have to read the file, and when doing so the same weird things appear again. – Gravity Assist Nov 18 '21 at 15:24
  • And again, it detects changes where it shouldn't, i can write the entire program without showing the text once, and it still would produce the same problem. – Gravity Assist Nov 18 '21 at 15:26
  • **What's the problem though?** I ran your code and it seems to be working correctly. Please spell it out explicitly. **What were your expected results, and what were your actual results?** I'm about to downvote and vote to close unless you can be explicitly clear about this. Those "weird things" aren't wrong, they're substitution characters. So please tell me what your expectations are. – Wyck Nov 18 '21 at 15:32
  • @Wyck Ok, ill try again, There is a ship which has the hex_code value of `32FF2B`, it shows in the raw data, but in the parsed data (JSON) i can't find the ship which has this hex code (i've modified the full code to show what i mean, the expected output is that it shows the index and the parsed ship, but it only shows the index, meaning it got lost in the parsing process) – Gravity Assist Nov 18 '21 at 15:38
  • 1
    The main problem is the missing [mcve]. Your example requires network communication and is not reproducible. You should add two responses to your question and remove the network communication. Reduce your code to the exact problem. – jabaa Nov 18 '21 at 15:40
  • I reinstalled node, now it seems to work. (but only with the buffer concat method) – Gravity Assist Nov 18 '21 at 15:47

1 Answers1

1

The problem could be that multi-byte sequences have arrived split into different chunks, and it doesn't make sense to turn any single chunk into a string by itself because some of the bytes of a character is in one chunk and the other bytes of that character are in the next chunk.

To get around this, just accumulate the incoming data chunks by keeping the the buffers they originally arrived in, and concatenate all the buffers (chunks) into a single buffer before turning them into a string.

Instead of data = '' do chunks = [], and instead of data += chunk; do chunks.push(chunk) and then in your 'end' handler, do data = Buffers.concat(chunks).toString('utf8').

    let chunks = [];
    resp.on('data', (chunk) => {
        chunks.push(chunk);
    });
    resp.on('end', async () => {
        let data = Buffer.concat(chunks).toString('utf8');
        try {
            //console.log(data)
            let result = JSON.parse(data.toString())["ships"];
            console.log(result)
        } catch (err) {
            console.log("Error: " + err.message);
        }
    });
Wyck
  • 10,311
  • 6
  • 39
  • 60