Search code examples
javascriptjsonnode.jsrequestrequestjs

node js: request js multipart 2nd level file and JSON.stringify


I'm trying to turn this CURL call into request.js

curl -i -X POST "https://api.soundcloud.com/tracks.json" \
            -F 'oauth_token=***' \
            -F 'track[asset_data][email protected]' \
            -F 'track[title]=Track title' \
            -F 'track[sharing]=public'

The interesting bit is that the file attachment ('asset_data') is on the 2nd level of the formData object.

THIS is not working:

var formData = {
  oauth_token: '***',
  track: {
    asset_data: fs.createReadStream('music.wav'),
    title: 'Track title',
    sharing: 'public'
  }

}
request.post({url:'http://service.com/upload', formData: formData}...

I know it's because the docs and this post say I have to embed the track inside of JSON.stringify(track)

but when I do that and the POST executes it comes back with "buffer":[],"length":0, I get the sense that it didn't wait for the file to stream before it stringify-ed it.

here's all the code in one place:

function postToSoundcloud(){
    var track = {'sharing': 'public',
                 'title': TRACK_NAME,
                 'asset_data': fs.createReadStream('music.wav')
                }
    var formData = {
        oauth_token: '***',
        track: JSON.stringify(track)
    };
    var req = request.post({url:'https://api.soundcloud.com/tracks.json', 'formData': formData}, function optionalCallback(err, httpResponse, body) {
        if (err) {
            return console.error('upload failed:', err);
        }
        console.log('Upload successful!  Server responded with:', body);
    }); 
}

If there are better approaches instead of using request.js I'm open to it. I can tell request.js is very popular, but also I'm very new to node.

thank you all very much


Solution

  • You need to format it just like you do for curl:

    var formData = {
      oauth_token: '***',
      'track[asset_data]': fs.createReadStream('music.wav'),
      'track[title]': 'Track title',
      'track[sharing]': 'public'
    }