33

In postman, I can successfully make this request:

enter image description here

And get this response:

enter image description here

Now I want to do the same request in my server.js file in node.js:

const fetch = require('node-fetch')
const SEN_URL =  "http://www.sentiment140.com/api/bulkClassifyJson" // URL of sentiment analysis
app.get('/api/sentimenttest', async (req, res) => {
  try{
    var sentiments = await fetch(SEN_URL, {method: "POST", body: {"data": [{"text": "I love you"}, {"text": "I hate you"}]}})
    console.log(sentiments)
    res.send(sentiments)
  }catch(error){
    console.log(error)
  }
})

This doesn't work. Here's what shows up in the browser when I go to localhost:5000/api/sentimenttest:

{"size":0,"timeout":0}

and here's the console output:

 Response {
   size: 0,
   timeout: 0,
   [Symbol(Body internals)]: 
    { body: 
       PassThrough {
         _readableState: [ReadableState],
         readable: true,
         _events: [Object],
         _eventsCount: 2,
         _maxListeners: undefined,
         _writableState: [WritableState],
         writable: false,
         allowHalfOpen: true,
         _transformState: [Object] },
      disturbed: false,
      error: null },
   [Symbol(Response internals)]: 
    { url: 'http://www.sentiment140.com/api/bulkClassifyJson',
      status: 200,
      statusText: 'OK',
      headers: Headers { [Symbol(map)]: [Object] } } }

Since the request works just fine in postman, I think that the problem is with node-fetch, or the way that I use it, specifically how the body parameter is provided in the fetch() call. It seems like the API call does not contain what I want it to, since in the browser it says "size":0.

What should I do to fix this?

Sahand
  • 7,980
  • 23
  • 69
  • 137
  • [node-fetch usage examples](https://www.npmjs.com/package/node-fetch) quite clearly show that you have to at least `JSON.stringify()` the body data or pass it in various other ways. – marekful Apr 15 '18 at 12:49

2 Answers2

37

You need to await for json.

var sentiments = await fetch(SEN_URL, {method: "POST", body: {"data": [{"text": "I love you"}, {"text": "I hate you"}]}})
//Here 
await sentiments.json()

Also you can make request with JSON.stringify() for body. And it will be easier to manage your js object. Like this:

var data = {data: [{text: "I love you"}, {text: "I hate you"}]};
var body = JSON.stringify(data);
var sentiments = await fetch(SEN_URL, { method: "POST", body: body });
Grynets
  • 2,477
  • 1
  • 17
  • 41
  • 12
    He _can_ and **must** use `JSON.stringify`, since it is required by the [`node-fetch`](https://www.npmjs.com/package/node-fetch) module for sending JSON in POST requests. – blex Apr 15 '18 at 12:50
  • Second await, the main point and first argument of your answer, is that really necessary? This was about JSON.stringify() only. – marekful Apr 15 '18 at 12:51
  • 3
    @marekful, actually, it was also necessary, removing it results in an empty JSON object being returned by the server. – Sahand Apr 15 '18 at 13:02
  • awesome solved the problem :) const resp = await fetch(factor2API_Endpoint.SEND_OTP_SMS(to)); console.log(await resp.json()); return await resp.json(); – Jatinder May 28 '22 at 09:09
1

Since it can be easily overlooked within the accepted best answer, just wanted to point out that it's especially crucial to return the response as response.json(). The await part can all be in place correctly and still result in OP's Response { size: 0, timeout: 0 etc } if the .json() method is left off. This whole thread is about POST requests but the same applies to GET etc too.

cf512
  • 71
  • 4