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
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.