I'm using request-json, found on npm, to query my API server. My server requires that an auth token be passed in the header, but using request-json's method of setting headers produces the following error:
Error: "name" and "value" are required for setHeader().
at ClientRequest.OutgoingMessage.setHeader (_http_outgoing.js:333:11)
at new ClientRequest (_http_client.js:101:14)
at Object.exports.request (http.js:49:10)
at Request.start (C:\Users\Michael\Desktop\FrescoWeb\node_modules\request-js
on\node_modules\request\request.js:904:30)
at Request.write (C:\Users\Michael\Desktop\FrescoWeb\node_modules\request-js
on\node_modules\request\request.js:1625:10)
at end (C:\Users\Michael\Desktop\FrescoWeb\node_modules\request-json\node_mo
dules\request\request.js:666:16)
at Immediate._onImmediate (C:\Users\Michael\Desktop\FrescoWeb\node_modules\r
equest-json\node_modules\request\request.js:690:7)
at processImmediate [as _immediateCallback] (timers.js:358:17)
I'm setting the header and hitting the endpoint in the following code:
var api = requestJson.createClient(config.API_URL);
api.headers['authtoken'] = req.session.token;
api.post(
'/v1/outlet/update',
params,
function(error, response, body){
if (error)
return res.json({err: error}).end();
if (!body)
return res.json({err: 'ERR_MISSING_BODY'}).end();
if (body.err)
return res.json({err: body.err}).end();
req.session.user.outlet = body.data;
req.session.save(function(){
res.json({}).end();
});
}
);
When I comment api.headers['authtoken'] = req.session.token; out, the call doesn't crash. Is there something that I am doing wrong, or do I have to migrate to request for http requests?
req.session.token should be req.session.user.token
Related
i am trying to do an authentitication using mysql and nodejs, and in the terminal returns an Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the cli
ent. how can i solve it?
res.json({
text:'protected'
});
});
app.post('/api/add',(req,res)=>{
const sql = 'INSERT INTO users SET ? ';
const userOBJ ={
users:req.body.name,
fullname:req.body.fullname,
email:req.body.email,
telephone:req.body.telephone,
password:req.body.password
};
connection.query(sql,userOBJ,err=>{
if(err)throw err;
res.send('added customer');
})
jwt.sign({user:userOBJ},'users',(err,token)=>{
res.json({
token
})
}
)
});
function verifyToken(req,res,next){
const bearerHeader =req.headers ['authorization']
if(typeof bearerHeader !=='undefined'){
const bearerToken= bearerHeader.split(' ')[1]
req.token =bearerToken
next()
}else{
res.sendStatus(403)
}
}````
In the '/api/add' route, you're calling both res.send() and res.json() on the same request. That will cause the error you see about headers already sent.
Pick one or the other as you can only send one response for each http request.
In addition, you have asynchronous issues and a lack of error handler handling on the database call. You need to nest the second block of code inside the database callback so they are sequenced appropriately and you need to actually send an error response if you get an error from your database.
Here you are using the two response in a api res.send() & res.json(), please send only one response for a request.
I am making an http request in an api using React Native with Axios, I can get json and parsear it when the callback is 200, however, for example, when I call a method, for example, to register the user and step an email from a user who is already registered, he returns me an error 400 (Bad Request) but he also brings a json with the error message ("user already registered"). I need to get this error message since it is variable in the API and show to the user, but when I try to give it a console.log I get the following error:
json's return is this:
and my call code looks like this:
How to get this json even with return 400 in catch?
Thank you.
inside of your catch Block, the error object also provides you with a response body
//... your request here
.catch(error => {
console.log('response: ', error.response.data);
});
console.log(error) is calling the toString method of the error object which doesn't show you the response body.
error.response.data should give you the right content. Take a look at this part of the axios docs
I have two issues but I believe the second issue will be fixed once the first is fixed (question title).
I am receiving JSON from woocommerce. I can call for this data by using fetch of course on client side and it looks as such in the code:
async componentDidMount() {
const response = await fetch('/products');
const json = await response.json();
this.setState({
data: json,
})
// other code ....
}
When I go on the browser I get this error regarding my json data:
Unhandled Rejection (SyntaxError): Unexpected token < in JSON at position 0
With the following error in the console.log:
index.js:6 GET http://localhost:3000/products 500 (Internal Server Error)
index.js:6 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
Once the webpage is refreshed...this all disappears, everything becomes A-OKAY, why? and how do I go about rectifying this?
My JSON data when consoled and the page refreshed returns an object - no '<' is there. Also I don't know why I get the 500 error shown above? I am learning node.js - so I think this is a server side issue as I had no issues before I split my code to client and server.
help?
What is happening is the data call you do takes time to load the data.
Till then the this.state.data is null. The error
Unexpected token < in JSON at position 0
is because you are trying to process the this.state.data but finds null. You need to make sure you handle what needs to be displayed when data is null.
Also, I think you don't need the await before response.json()
The 500 server error is a server side issue.
To stop this whole refreshing the page issue; I had to fix my server file (node.js of course)
My get request had originally looked like this:
let response;
app.get('/products', (req, res, err) => {
WooCommerce.get('products', function(err, data, res) {
response = res;
});
res.status(200).json(JSON.parse(response));
});
The issue here was that I was calling /products with fetch which url didn't point to anything but another API call, which only got called once I forced it pass the first url call I guess using a page refresh. Forgive my understanding here.
The correct code was calling Woocommerce api first then passing its response to the /product url so I can fetch it in the front end, like so;
let response;
WooCommerce.get('products', function(err, data, res) {
response = res;
app.get('/products', (req, res, err) => {
if (res.status(200)) {
res.status(200).json(JSON.parse(response));
} else {
console.log('theres an error', err);
}
})
});
And Tarrrrdaaa no refresh issue/SyntaxError error!!!
As one of the answers says, this error happens when you try to parse a nullish value. You can fix this issue by making sure the data is defined before trying to parse it:
if(data){
JSON.parse(data);
}
I'm using axios to send a JSON object as a parameter to my api. Before it post request is fired, my data starts of as a JSON object. On the server side, when I console.log(req.params) the data is returned as such
[object Object]
When I used typeof, it returned a string. So then I went to use JSON.parse(). However, when I used that, it returned an error as such
SyntaxError: Unexpected token o in JSON at position 1
I looked for solutions, but nothing I tried seemed to work. Now I'm thinking I'm sending the data to the server incorrectly.
Here's my post request using axios:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/${mediaData}`)
return json;
}
Any thoughts on how I can solve this?
You need to update your code using axios to provide the mediaData in the body of the request instead of the URL:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/`, mediaData)
return json;
}
In the backend (assuming you're using express here), you need to configure your application to use bodyParser:
var express = require('express')
, app = express.createServer();
app.use(express.bodyParser());
And then in your controller update your console.log(req.params) to console.log(req.body); then restart your node server
I'm using the following to read Twitter json. It works with one uri and not another. The uri's work with the Twitter API console but not Xamarin.Social. I have read and write permissions on the Twitter app so I can't see where I'm going wrong.
https://api.twitter.com/1.1/account/settings.json <-- works
https://api.twitter.com/1.1/users/show.json?screen_name=AUserName <-- fails (see error below)
request.GetResponseAsync ().ContinueWith (response => {
if (response.IsFaulted)
{
Console.WriteLine (response.Exception.Flatten ());
}
var json = response.Result.GetResponseText ();
System.AggregateException: One or more errors occured ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0030c] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1606
at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00141] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1423
--- End of inner exception stack trace ---
--> (Inner exception 0) System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0030c] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1606
at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00141] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1423
[quick google search gave this but not sure if its relevant: https://dev.twitter.com/discussions/15206]
// UPDATE ***********
Does this extra infor help or you need more details? If so then what details are required?
public Account Account
{
get
{
var task = Service.GetAccountsAsync ()
.ContinueWith (accounts =>
{
return accounts.Result.ToList ().FirstOrDefault ();
});
return task.Result;
}
set
{
AccountStore.Create ().Save (value, SocialPlatform.ToString ());
}
}
// later on
// when endpoint = "https://api.twitter.com/1.1/account/settings.json" <-- works, json returned
// when endpoint = "https://api.twitter.com/1.1/users/show.json?screen_name=XXXX" <-- IsFaulted with above error,
var request = Service.CreateRequest ("GET", endpoint, Account);
request.GetResponseAsync ().ContinueWith (response => {
if (response.IsFaulted)
{
Console.WriteLine (response.Exception.Flatten ());
return;
}
var json = response.Result.GetResponseText ();
Console.WriteLine (json);
});
It seems like you are not authorised when you make this call.
From Xamarin.Social documentation.
Xamarin.Social uses the Xamarin.Auth library to fetch and store
Account objects.
Each service exposes a GetAuthenticateUI method that returns a
Xamarin.Auth.Authenticator object that you can use to authenticate the
user. Doing so will automatically store the authenticated account so
that it can be used later.
The reason why it works in Twitter API console is that you have authorised there prior to making a call.
If you are already authorising in your app then please post the code you use to authorise.