Got: Unable to send file through form-data with got

Created on 12 Dec 2018  路  3Comments  路  Source: sindresorhus/got

What would you like to discuss?

In the README, a code snippet suggests using the form-data module when using got.

I tried it, and alas I can't seem to make it work. This seems to be a problem with form-data but all issues I'm finding on its github don't seem to involve got, so I'd like some help if that's possible

here's my code :

import formData from 'form-data';
import {resolve} from 'path';
import {createReadStream} from 'fs';
import {getConfig} from './config';

const form = new formData();
const conf = getConfig();
const user = {
 avatar_file: 'abc.png'
}
form.append('avatarfile', createReadStream(resolve(conf.appPath, conf.PathAvatars, user.avatar_file)));
form.append('nickname', user.nickname);
form.append('bio', user.bio);
form.append('email', user.email);
form.append('url', user.url);

try {
        got(`http://myurl/api/users/user1`, {
            method: 'PUT',
            body: form,
            form: true,
            headers: {
                authorization: someToken
            }
        });
    } catch(err) {
        throw `Remote update failed : ${err}`;
        }

Here's the error I get :

TypeError: Cannot read property 'name' of null
    at FormData._getContentDisposition (D:\perso\toyundamugen-app\node_modules\f
orm-data\lib\form_data.js:226:40)
    at FormData._multiPartHeader (D:\perso\toyundamugen-app\node_modules\form-da
ta\lib\form_data.js:177:33)
    at FormData.append (D:\perso\toyundamugen-app\node_modules\form-data\lib\for
m_data.js:70:21)
    at editRemoteUser (D:/perso/karaokemugen-app/src/_services/user.js:67:19)

I tried a few things, like I saw in form-data/form-data#220 for example, but they just bring other errors (like source.on is not a function) so I'm a little lost there.

Is there an easier way with got, perhaps without using form-data, to send files along with other data to an API entrypoint ?

Thanks in advance

Checklist

  • [X] I have read the documentation.
documentation

All 3 comments

Well, after trial and error and looking through form-data's code, I found what was wrong : you actually have to specify an options object after the readable stream.

The part about it in got's readme says :

form.append('my_file', fs.createReadStream('/foo/bar.jpg'));

While it should be

form.append('my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg');

Options can be either an object or a string.

Updating the readme would be nice :) (form-data's readme seems wrong as well)

Thanks for sharing the possible improvement. I checked our example 馃槃 .

I also took the liberty to debug your code. form-data's error is indeed quite cryptic (I'll open an issue in form-data). The only issue is that you're passing undefined as a value to append. Here's an annotated version of your code that highlights the problem:

const got = require('got');
const FormData = require('form-data');

const form = new FormData();
const user = { avatar_file: 'abc.png' }; // no nickname in here

form.append('nickname', user.nickname); // <- you're passing undefined here

got('http://requestbin.fullcontact.com/18qsbve1', {
    method: 'PUT',
    body: form,
})
    .then(res => { res.statusCode === 200 && console.log('yay!'); })
    .catch(() => { console.error('Uh oh'); });

So got actually never got the formdata! The code blew up before that point. Good luck with the rest of the app 馃檶 !

Thanks for pointing that out : I noticed that as well after writing this post but didn't think to report it back here.

I spent a lot of time on this so I don't really want to experiment further with this now that it works :)

What's a bit weird though is that I'm pretty sure form-data's code is pretty confusing and led me to believe it absolutely needed an options argument.

Was this page helpful?
0 / 5 - 0 ratings