I'm just following tutorials and figuring out how to handle get requests in NodeJS.
Here are snippets of my code:
NodeJS:
router.get('/test', function(request, response, next) {
console.log("Received Get Request");
response.jsonp({
data: 'test'
});
});
Angular:
$http.get("http://localhost:3000/test").
success(function(response) {
alert("OK");
}).
error(function(response) {
alert("FAIL");
});
If I try to access the link directly # localhost:3000/test, I'm able to receive the JSON message correctly. But when I use angularJS $http call, the request always fails and I'll find this error in the network inspector (Response)
SyntaxError:JSON.parse:unexpected end of data at line 1 column 1 of
the JSON data
The reason for that is because the response is empty but the response code is 200 in both cases.
I've tried searching for hours but maybe someone can enlighten me on this?
you could try and send
res.send('test')
and then on your http request you can use 'then'
$http.get("http://localhost:3000/test").then(function(res) {
console.log(res);
})
unlike success, then will give you a complete object (with 'test' - string as res.data)
success will bring you only the data;
then will bring you the whole object (with the status and such)..
now about that jsonp .. it's used to override a json response. you could simply use 'res.json({data: 'test'})' and it should also work for you..
hope it helps
You're using jsonp in node, which you probably don't need to. This adds extra characters to the response and so the JSON parser fails to parse (that's what the error is telling you, the JSON is malformed)
Try changing the server to look like
response.json({
data: 'test'
});
If you look in the Network pane of the developer tools, you should be able to see the raw response. It should look something like:
{"data" : "test"}
Related
I am new to angular 10 and I am trying to make an http post to a PHP file as shown below
this.http.post(`${environment.server}/path/file.php`, {param1, param2})
.subscribe(
data => {
console.log(JSON.stringify(data));
},
error => {
console.log(error);
this.error = error;
});
The file is successfully called and returns the following JSON as displayed in the console response
{"Email":null,"school_year":2021,"academic_year":"2021"}
When I make the request I am immediately taken to the error state and all the console log is showing below only prints "OK"
console.log(error);
The two questions are the following
Why am getting to the error when the file is successfully returning JSON
Is there a way to get a more helpful error message than just OK
You will need to set the content type to application/json
You would be better off if you used a rest API rather than using php files. .NET Core or Node.JS would give you a better development experience.
It seems that your back-end PHP send the response with status code 400. It should be revised to 200 to get the data in response. When Status code is in Error range like 400, 401, 403 ... http Response will resolved in error or catch part.
In addition if you want just get data, it's better to use GET instead of POST.
I've got this cURL request working perfectly on remote interface just as it should
curl -XGET "https://server.host:8080/peregrine" -d '{"exchanges":["kucoin", "kraken"],"volume":10}' -k
I'm trying to build a little frontend app with Vue.js and need the above converted to an Axios get request.
I've been trying the following so far:
axios({
method: 'get',
url: 'https://server.host/peregrine',
data: {"exchanges":["kucoin", "kraken"],"volume":10}
});
putting params instead of data makes it a URL and remote server says that it received no data.
What am I doing wrong? Thanks.
Likely the problem could be that using GET you cannot pass data like you are doing. You have to pass them as query parameter.
Try to change your call with:
axios.get('https://server.host/peregrine', {
params: {"exchanges":["kucoin", "kraken"],"volume":10}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});
GET requests should not have request bodies.
CURL will allow you to make a GET request with one, but XMLHttpRequest and fetch (the HTTP APIs in browsers which axios wraps) will not.
Make a POST request instead. You might need to change the server-side code to support this.
Thanks for your replies!
Indeed there's no way to send data body with axios.get()
We ended up tuning the server side to accept normal generic GET requests. Thanks again to everyone who answered!
I am creating a rest api , I would like to retrieve or get all reviews/comments which are in a database.
This is what I have done :
app.get('/review', (req, res) =>{
request('https://api.themoviedb.org/3/review?api_key=4d9c9de3bdf0d3b6837c49c086e3b190', function (error, response, body) {
console.log('error:', error); // Print the error if one occurred and handle it
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
res.send(body)
});
});
I am getting this error:
{"status_code":34,"status_message":"The resource you requested could not be found."}
what am I doing wrong here? help
Note: other methods works perfectly
This isn't a JS error or anything. If you look at the API Documentation, status_code: 34 means you're accessing an endpoint that doesn't exist.
Diving into the docs a bit further, you can't get ALL the reviews in the database. All you can do is get the reviews on a per movie basis. Try this URL:
https://api.themoviedb.org/3/movie/401478/reviews?api_key=4d9c9de3bdf0d3b6837c49c086e3b190
Here's the documentation on the /movie/<movie_id>/reviews endpoint: https://developers.themoviedb.org/3/movies/get-movie-reviews
There is also the /review/<review_id> end point, but it appears that gets a single review by id which probably isn't what you're looking for:
https://developers.themoviedb.org/3/reviews/get-review-details
It has nothing to do with nodeJS.As stated by #VicJordan, the problem is only with the url you are trying to search, it's simply not a valid API request. Try to go thru API documentation to find out how to use them. An example of a valid URL would be:
https://api.themoviedb.org/3/discover/movie?api_key=4d9c9de3bdf0d3b6837c49c086e3b190
I am trying to send a new push subscription to my server but am encountering an error "Uncaught (in promise) SyntaxError: Unexpected end of JSON input" and the console says it's in my index page at line 1, which obviously is not the case.
The function where I suspect the problem occurring (because error is not thrown when I comment it out) is sendSubscriptionToBackEnd(subscription) which is called in the following:
function updateSubscriptionOnServer(subscription) {
const subscriptionJson = document.querySelector('.js-subscription-json');
const subscriptionDetails = document.querySelector('.js-subscription-details');
if (subscription) {
subscriptionJson.textContent = JSON.stringify(subscription);
sendSubscriptionToBackEnd(subscription);
subscriptionDetails.classList.remove('is-invisible');
} else {
subscriptionDetails.classList.add('is-invisible');
}
}
The function itself (which precedes the above function):
function sendSubscriptionToBackEnd(subscription) {
return fetch('/path/to/app/savesub.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
})
.then(function(response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function(responseData) {
if (!(responseData.data && responseData.data.success)) {
throw new Error('Bad response from server.');
}
});
}
I have tried replacing single quotes with double quotes in the fetch call but that yields the same results.
I know that the JSON should be populated because it prints to the screen in the updateSubscriptionOnServer() function with subscriptionJson.textContent = JSON.stringify(subscription);, and I used that output in the google codelab's example server to receive a push successfully.
EDIT: Here is the JSON as a string, but I don't see a mistake in syntax:
{"endpoint":"https://fcm.googleapis.com/fcm/send/dLmthm1wZuc:APA91bGULRezL7SzZKywF2wiS50hXNaLqjJxJ869y8wiWLA3Y_1pHqTI458VIhJZkyOsRMO2xBS77erpmKUp-Tg0sMkYHkuUJCI8wEid1jMESeO2ExjNhNC9OS1DQT2j05BaRgckFbCN","keys":{"p256dh":"BBz2c7S5uiKR-SE2fYJrjPaxuAiFiLogxsJbl8S1A_fQrOEH4_LQjp8qocIxOFEicpcf4PHZksAtA8zKJG9pMzs=","auth":"VOHh5P-1ZTupRXTMs4VhlQ=="}}
Any ideas??
This might be a problem with the endpoint not passing the appropriate parameters in the response's header.
In Chrome's console, inside the Network tab, check the headers sent by the endpoint and it should contain this:
Example of proper response to allow requests from localhost and cross domains requests
Ask the API developer to include this in the headers:
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
This happened to me also when I was running a server with Express.js and using Brave browser. In my case it was the CORs problem. I did the following and it solved the problem in my case:
(since this is an Express framework, I am using app.get)
-on the server side:
res.set({
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
});
-on client side I used Fetch to get data but disabled the CORS option
// mode: "no-cors" //disabled this in Fetch
That took care of my issues with fetching data with Express
This can be because you're not sending any JSON from the server
OR
This can be because you're sending invalid JSON.
Your code might look like
res.end();
One of the pitfalls is that returned data that is not a JSON but just a plain text payload regardless of headers set. I.e. sending out in Express via something like
res.send({a: "b"});
rather than
res.json({a: "b"});
would return this confusing error. Not easy to detect in network activity as it looks quite legit.
For someone looking here later. I received this error not because of my headers but because I was not recursively appending the response body to a string to JSON.parse later.
As per the MDN example (I've taken out some parts of their example not immediately relevant):
reader.read().then(function processText({ done, value }) {
if (done) {
console.log("Stream complete");
return;
}
result += chunk;
return reader.read().then(processText);
});
For my issue I had to
Use a named function (not an anonymous ()=>{}) inside the .then
Append the result together recursively.
Once done is true execute something else on the total appended result
Just in case this is helpful for you in the future and your issue is not header related, but related to the done value not being true with the initial JSON stream response.
I know this question has already been answered but just thought I add my thoughts.
This will happen when your response body is empty and response.json() is expecting a JSON string. Make sure that your API is returning a response body in JSON format if must be.
I am having a serious issue with Angularjs and jQuery with this particular REST API. I am not in the same domain as said API, and can get the data back, however I am getting a "SyntaxError: invalid label "name" :{" error.
If I were to do something like $http.get or $.get I get a timeout after 10 seconds. However, if I use jsonp with either library I will see in Firebug that the data is returned in the net tab, however I get the error above in the console tab. After doing some research, I have seen plenty of people having issue with the API (a Jive product) and this specific line of text that is returned along with the JSON. The response looks something like this:
throw 'allowIllegalResourceCall is false.';
{"name":{ "givenName": "xxx"}}
The big problem is the first "throw" line. I have tried a bunch of ways to remove that line but I haven't found the proper way to do it. I apologize for not being able to provide a code sample, but if there is any way to get this work in Angularjs or jQuery, I will take it. I don't know if the answer lies in Angularjs interceptors, or transformResponse.
Any help that can be provided will be appreciated.
Thank you
AngularJs allows you do define the methods for transforming the http response data (so you can remove the first line of the response data). You can do this either for a single request or add a httpInterceptor.
Single request:
$http.get('...', {
transformResponse: $http.defaults.transformResponse.unshift(function(data) {
// Remove first line of response
data.split("\n").slice(1).join("\n")
}
});
HttpInterceptor
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
'request': function(config) {
config.transformResponse.unshift(function(data) {
return data.split("\n").slice(1).join("\n")
})
return config;
}
}
})
}])
Plunker: http://plnkr.co/edit/6WCxcpmRKxIivl4yK4Fc?p=preview