umutm
umutm

Reputation: 2894

nodejs - first argument must be a string or Buffer - when using response.write with http.request

I'm simply trying to create a node server that outputs the HTTP status of a given URL.

When I try to flush the response with res.write, I get the error: throw new TypeError('first argument must be a string or Buffer');

But if I replace them with console.log, everything is fine (but I need to write them to the browser not the console).

The code is

var server = http.createServer(function (req, res) {
    res.writeHead(200, {"Content-Type": "text/plain"});

    request({
        uri: 'http://www.google.com',
        method: 'GET',
        maxRedirects:3
    }, function(error, response, body) {
        if (!error) {
            res.write(response.statusCode);
        } else {
            //response.end(error);
            res.write(error);
        }
    });     

    res.end();
});
server.listen(9999);

I believe I should add a callback somewhere but pretty confused and any help is appreciated.

Upvotes: 109

Views: 314626

Answers (8)

Alexander Mills
Alexander Mills

Reputation: 100090

I get this error message and it mentions options.body

I had this originally

request.post({
    url: apiServerBaseUrl + '/v1/verify',
    body: {
        email: req.user.email
    }
});

I changed it to this:

request.post({
    url: apiServerBaseUrl + '/v1/verify',
    body: JSON.stringify({
        email: req.user.email
    })
});

and it seems to work now without the error message...seems like bug though. I think this is the more official way to do it:

 request.post({
        url: apiServerBaseUrl + '/v1/verify',
        json: true,
        body: {
            email: req.user.email
        }
    });

Upvotes: 58

A. PRABIN SARAB
A. PRABIN SARAB

Reputation: 41

The first argument must be one of type string or Buffer. Received type object

 at write_

I was getting like the above error while I passing body data to the request module.

I have passed another parameter that is JSON: true and its working.

var option={
url:"https://myfirstwebsite/v1/appdata",
json:true,
body:{name:'xyz',age:30},
headers://my credential
}
rp(option)
.then((res)=>{
res.send({response:res});})
.catch((error)=>{
res.send({response:error});})

Upvotes: 0

Gaurav Agarwal
Gaurav Agarwal

Reputation: 14843

Request takes a callback method, its async! So I am assuming, by the time the callback is executed the res.end() might get called. Try closing the request within the callback.

Upvotes: 33

Mr.X
Mr.X

Reputation: 31247

Although the question is solved, sharing knowledge for clarification of the correct meaning of the error.

The error says that the parameter needed to the concerned breaking function is not in the required format i.e. string or Buffer

The solution is to change the parameter to string

breakingFunction(JSON.stringify(offendingParameter), ... other params...);

or buffer

breakingFunction(BSON.serialize(offendingParameter), ... other params...);

Upvotes: 1

Prajith P
Prajith P

Reputation: 69

And there is another possibility (not in this case) when working with ajax(XMLhttpRequest), while sending information back to the client end you should use res.send(responsetext) instead of res.end(responsetext)

Upvotes: 1

Mohsin Muzawar
Mohsin Muzawar

Reputation: 1212

if u want to write a JSON object to the response then change the header content type to application/json

response.writeHead(200, {"Content-Type": "application/json"});
var d = new Date(parseURL.query.iso);
var postData = {
    "hour" : d.getHours(),
    "minute" : d.getMinutes(),
    "second" : d.getSeconds()
}
response.write(postData)
response.end();

Upvotes: 1

loganfsmyth
loganfsmyth

Reputation: 161487

response.statusCode is a number, e.g. response.statusCode === 200, not '200'. As the error message says, write expects a string or Buffer object, so you must convert it.

res.write(response.statusCode.toString());

You are also correct about your callback comment though. res.end(); should be inside the callback, just below your write calls.

Upvotes: 54

freakish
freakish

Reputation: 56487

Well, obviously you are trying to send something which is not a string or buffer. :) It works with console, because console accepts anything. Simple example:

var obj = { test : "test" };
console.log( obj ); // works
res.write( obj ); // fails

One way to convert anything to string is to do that:

res.write( "" + obj );

whenever you are trying to send something. The other way is to call .toString() method:

res.write( obj.toString( ) );

Note that it still might not be what you are looking for. You should always pass strings/buffers to .write without such tricks.

As a side note: I assume that request is a asynchronous operation. If that's the case, then res.end(); will be called before any writing, i.e. any writing will fail anyway ( because the connection will be closed at that point ). Move that line into the handler:

request({
    uri: 'http://www.google.com',
    method: 'GET',
    maxRedirects:3
}, function(error, response, body) {
    if (!error) {
        res.write(response.statusCode);
    } else {
        //response.end(error);
        res.write(error);
    }
    res.end( );
});

Upvotes: 14

Related Questions