Saving a picture to a document after retrieving it through an HTTP request in a Node application

I seem to be overlooking something obvious, but here's the issue - I am receiving a PNG from a Mapbox call with the intention of saving it to the file system and then serving it to the client. I have successfully made the call, received raw data as a response, and written a file. However, no matter what approach I take, the file seems to end up truncated. I have tried various solutions found online without success. I have logged the raw response, which appears complete, yet any file I create only contains a chunk of unreadable data.

Below is the current code I am using for creating the file. I resorted to this buffer manipulation after multiple failed attempts. Any assistance would be greatly appreciated.

module.exports = function(req, res, cb) {
    var cartography = function() {
        return https.get({
            hostname: 'api.mapbox.com',
            path: '/v4/mapbox.wheatpaste/' + req.body[0] + ',' + req.body[1] + ',6/750x350.png?access_token=' + process.env.MAPBOX_API
        }, function(res) {
            var body = '';
            res.on('data', function(chunk) {
                body += chunk;
            });
            res.on('end', function() {
                var mapPath = 'map' + req.body[0] + req.body[1] + '.png';
                var map = new Buffer(body, 'base64');
                fs.writeFile(__dirname + '/client/images/maps/' + mapPath, map, 'base64', function(err) {
                    if (err) throw err;
                    cb(mapPath);
                })
            })
        });
    };
    
    cartography();
};

Answer №1

If you're looking to make your code more concise, consider the following optimized subroutine:

    const fs = require('fs');
    const https = require('https');

    https.get(url, (response)=> { // initiating the request
        if(response) {
            let imageName = 'image.png'; // typically using crypto for generating unique names
            response.pipe( // piping the response to a write stream (file)
                fs.createWriteStream( // creating a write stream
                    './public/' + imageName // creating a file with the name image.png
                )
            );
            return imageName; // assuming 'public' folder is set as default in app.js
        } else {
            return false;
        }
    })

You have the option to extract the original name and extension from the URL, but it's recommended to generate a new name using crypto and determine the file extension either from the URL or by utilizing modules like read-chunk and file-type.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The difference between calling a function in the window.onload and in the body of a

In this HTML code snippet, I am trying to display the Colorado state flag using a canvas. However, I noticed that in order for the flag to be drawn correctly, I had to move certain lines of code from the window.onload() function to the drawLogo() function. ...

Hidden Password Field Option in HTML

My HTML password textbox has the input type set as password, but I can still see what is being typed. This shouldn't happen as password inputs should be masked. Can someone please advise me on how to resolve this issue? To replicate, copy the code be ...

`How can I retrieve environment variables in React or inject them into a React application?`

I attempted to include the following code in the plugins section of my webpack configuration, but it resulted in an unusable build. It's worth noting that I am not using create-react-app. new webpack.DefinePlugin({ 'process.env': dotenv. ...

Create a variety of charts using the same data object in Highcharts

Is it possible to display two (or three) different charts on the same page using Highcharts without creating separate div elements and only utilizing one object? I have created a screenshot to illustrate my question: You can view the code example on JSFi ...

Unleashing the Power of Lodash Debounce in Vue

Currently, I have integrated debounce from lodash into my main.js file. import lodash from 'lodash' Vue.prototype._ = lodash I've been utilizing it like this._.find(...), and everything has been functioning smoothly. However, when attemptin ...

Next.js is failing to detect the @lib folder

I am currently working on a Next JS project. Within my project, I have a specific directory structure: src Within this src directory, I have subdirectories such as pages, styles, lib Inside the lib directory, there is a file named config.js This file co ...

Provide solely the specified content range

While working with Node.js, my goal is to develop a video server that can serve a specific portion of a larger media file. Thanks to this gist, I have successfully created a video server and integrated it with an HTML5 video player using: <video contr ...

Failed to load Gulpfile.js in the Task Runner Explorer of Visual Studio 2019 version 16.6.2

Displayed below is the result in the output error window. Failed to execute "D:\TortSVN\Oil Diversity\Main Web App\LatsetOildiversity\Gulpfile.js"... cmd.exe /c gulp --tasks-simple fs.js:27 const { Math, Object } = primordials; ...

How can I display a Skeleton when pressing pagination buttons and then turn it off after 3 seconds?

Here is a snippet of my code featuring the use of a Skeleton as a placeholder for CardMedia: {loading ? ( <Skeleton variant="rectangular" width={308} height={420} animation="wave" /> ) : ( <CardMedia s ...

Error: The 'replace' property of null cannot be read in select2

In my Node Express app, I am incorporating select2, and encountering an error when supplying an array as the data source with data: dataBase. The issue arises as Uncaught TypeError: Cannot read property 'replace' of null. Although using an ajax ...

Creating a dynamic step animation with jQuery: A step-by-step guide

Struggling to find resources on how to animate a color wheel using jQuery? Want to create a spiraling effect by gradually revealing colors at 45-degree intervals, like a loading GIF spiral? I need it to cycle through the defined colors in order and then cl ...

Tips for verifying elements using the Loop technique in a JSON array

I am new to JavaScript and I have been trying to run the following code with an expected result like this: [["00:04:12","05:54:46"],["06:06:42","12:45:22"],["12:51:11","15:56:11"]] However, my script is not working as expected. Can someone please help ...

My REACT App is experiencing difficulties with routing

I am facing an issue with my REACT App. It works perfectly on my local host, but when deployed on Heroku, it behaves differently. Here is the problem: On my local host, the main page of the app has a navbar with various options, including Tickets. Clickin ...

Display my additional HTML content on the current page

Is it possible for my addon to open a predefined html page in the current window when it is started? And if so, how can this be achieved? Currently, I am able to open my addon page in a new window using the following command: bridge.boot = function() { ...

I am working with Vue.js 2.0 and attempting to send an event from a `child component`

I've been working with Vue.js 2.0 and I'm facing an issue trying to emit an event from a child component to the parent component, but unfortunately, it's not functioning as expected. Here is a glimpse of my code: child component: <temp ...

Creating a simulation of browser cookies using Javascript

I've embarked on a mission to develop a comprehensive web proxy using node.js that downloads webpages and directly showcases them to the client. The implementation of cookies has proven to be trickier than expected, given their myriad rules and comple ...

Encounter with Google error while using passport authentication with node.js

I am currently working on integrating passport with an express/node.js application. I'm facing an issue where I am unable to authenticate using Google. The error message returned by Google is as follows: Error: invalid_request Error in parsing the ...

Restricting the input field in jQuery to only accept the maximum value based on the

There are two input fields: discountType and discountAmount. My goal is to set restrictions based on the value of discountType: if it's percentage, the discountAmount input should only accept numbers between 0 and 100; if it's absolute, any numbe ...

Customize the appearance of radio buttons in HTML by removing the bullets

Is there a way for a specific form component to function as radio buttons, with only one option selectable at a time, without displaying the actual radio bullets? I am looking for alternative presentation methods like highlighting the selected option or ...

Looking to incorporate React Canary in raw HTML? Or perhaps interested in adding react-dom/client into your project?

Due to certain undisclosed reasons, I am developing a React application without the use of bundlers like webpack. Instead, I simply include React and ReactDOM using <script> tags in my index.html, fetching them from a CDN: https://cdnjs.cloudflare.co ...