Node-fetch problems with POST requests
Asked Answered
F

2

35

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?

Fusco answered 15/4, 2018 at 12:37 Comment(1)
node-fetch usage examples quite clearly show that you have to at least JSON.stringify() the body data or pass it in various other ways.Winded
S
39

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 });
Singlestick answered 15/4, 2018 at 12:44 Comment(4)
He can and must use JSON.stringify, since it is required by the node-fetch module for sending JSON in POST requests.Razzledazzle
Second await, the main point and first argument of your answer, is that really necessary? This was about JSON.stringify() only.Winded
@marekful, actually, it was also necessary, removing it results in an empty JSON object being returned by the server.Fusco
awesome solved the problem :) const resp = await fetch(factor2API_Endpoint.SEND_OTP_SMS(to)); console.log(await resp.json()); return await resp.json();Cosma
U
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.

Ultramicroscopic answered 4/10, 2022 at 7:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.