Scenario
I've had a problem for 4 hours, I'm trying to send an http get request while sending the user ID as a parameter. I try a lot of examples found on the net but I still have this error on the backend side.
GET http://localhost:3000/api/users/getusersbyid/?userId=00c1308a-32ad-48a0-8737-d4682b2b504e 500 (Internal Server Error)
Here is my JS function code:
async function getUserById() {
try {
await $.ajax({
type: "GET",
url: "http://localhost:3000/api/users/getusersbyid",
data: {
userId: "00c1308a-32ad-48a0-8737-d4682b2b504e"
},
contentType: "application/x-www-form-urlencoded"
}).done(function(response) {
console.log(response);
}).fail(function(err) {
console.log(err);
});
} catch (error) {
console.log(error);
}
}
Here is my Backend function code using NodeJs:
getUserById: function(req, res) {
let userId = req.body.userId;
models.User.findOne({
where: {
id: userId
},
include: [{
model: models.TypeUser,
attributes: ['code', 'value']
}]
}).then(function(data) {
if (data) {
res.status(201).json({
'status': 'success',
'code': 201,
'data': data
});
} else {
res.status(404).json({
'status': 'falled',
'code': 404,
'message': 'Unable to find one or more users'
});
}
}).catch(function(err) {
res.status(500).json({
'status': 'falled',
'code': 500,
'message': 'An internal error has occurred',
'data': err
});
});
}
Here is my Backend Error Message image:
Need your help and suggestions
It seems something's going on in your backend. Have you tried using logging, for example after your "let userId = req.body.userId;" line to see if your server is receiving the userId?
console.log("backend received userId="+userId)
I just solved the problem after reading the answers from #AbhishekKumawat and from #Pointy. So using the "GET" method, I should do this:
let userId = req.query.userId;
instead.
let userId = req.body.userId;
Related
I'm using axios and an API to get a page's HTML, editing the HTML, and putting it back via a POST request to the API. I'm successful in retrieving and editing the HTML but I can't figure out how to put it back/change the webpage's HTML.
I tried using a PUT request instead of a POST request, but I get a 405 error that the PUT method is not allowed for the webpage.
axios.get(url, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
version = response.data.version.number;
body = response.data.body.storage.value;
// takes the body HTML and formats all the links
newBody = middleware.formatLinks(body);
data = {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
// put the body HTML back into the page
axios.post(url, {
data: {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
}, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
console.log(response.data);
})
.catch( (error) => {
console.log(error);
})
})
.catch( (error) => {
console.log(error);
})
I expect the page to now be updated with all the links formatted to my liking. However the page is unchanged. When I console.log(response.data) after making the post request, the output is a string of newBody, when I expect it to be the JSON object
data: {
'type': 'page',
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
As mentioned in my comment in #Aman Raj's answer, I have the code working in python but translating it to nodejs was giving me issues. So I circumvented my problem by calling my python script in nodejs with the python-shell package.
let {PythonShell} = require('python-shell');
...
const formatLinks = (id) => {
let options = {
mode: 'text',
pythonOptions: ['-u'], // get print results in real-time
scriptPath: './python/', // path to my python scripts
// pass in the page id, username, and password to API request
args: [id, USERNAME, PASSWORD]
};
PythonShell.run('script.py', options, (err, results) => {
if (err) throw err;
// results is an array consisting of messages collected during execution
console.log('results: %j', results);
});
}
Your code seems fine. It may be possible that you are accessing an API which does not support editing it.
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response
status code indicates that the request method is known by the server
but is not supported by the target resource.
I get a 403 "You must specify an API key to make request" when trying to get data from a 3rd party API (Klaviyo).
const { id } = req.body
request.get({
url: `https://a.klaviyo.com/api/v1/person/${id}`,
headers: {
api_key: process.env.KLAVIYO_API_KEY
}
}, (error, response, body) => {
const profile = JSON.parse(body)
console.log(profile)
if (response.statusCode === 200) {
res.json({ profile, status: 201 })
} else {
res.json({ error: 'Did not get customer data', status: 500, response: response, err: error })
}
})
I've also tried with:
headers: {"Authorization": [API_KEY]}
data: {api_key: [API_KEY]}
Solution:
const { id } = req.body
request.get({
url: `https://a.klaviyo.com/api/v1/person/${id}`,
qs: {
api_key: process.env.KLAVIYO_API_KEY
}
}, (error, response, body) => {
const profile = JSON.parse(body)
console.log(profile)
if (response.statusCode === 200) {
res.json({ profile, status: 201 })
} else {
res.json({ error: 'Did not get customer data', status: 500, response: response, err: error })
}
})
Short answer: add it under params.api_key (as part of the GET request).
From the klaviyo documentation:
"You authenticate to the People API by providing one of your private API keys as part of each request. (...) Authentication happens via the api_key parameter in each request. It can be sent as part of the GET or POST parameters."
I think you are using GET request with POST header method. In GET you need to put it in URL
I managed to fetch video data from a channel but when it try to add comments to a video, I fail. So at some point I can read data successfully.
I have read that docummentation: https://developers.google.com/youtube/v3/docs/commentThreads/insert
And I'm not sure if I did the parameters correctly.
Besides Node.js and Express I'm using the request-promise package for promises if that's worth to mention.
const optionsComment = {
method: 'POST',
uri: 'https://www.googleapis.com/youtube/v3/commentThreads',
qs: {
part: 'snippet',
'snippet.channelId': 'a channel id',
'snippet.videoId': 'some video id',
'snippet.topLevelComment.snippet.textOriginal': 'a nice message',
key: "my key"
},
json: true
};
rp(optionsComment)
.then(result=>{
console.log("result of adding comment:", result);
})
.catch(function(err){
console.log("error during add comment");
console.log(err);
});
When I run the code I get this error:
error during add comment
{ StatusCodeError: 401 - {"error":{"errors":[{"domain":"global","reason":"required","message":"Login Required","locationType":"header","location":"Authorization"}],"code":401,"message":"Login Required"}}
at new StatusCodeError
Even if I'm logged in and try to comment my own video I get this error.
Maybe someone can give me a hint.
Thank you!
I'd similar issue as yours, sending the access_token in qs fixed it for me.
'use strict';
let request = require('request');
const sourceId = '< youtube video id>';
const comment_id = 'the comment id';
const comment = 'actual comment';
new Promise((resolve, reject) => {
request({
method: 'POST',
url: 'https://www.googleapis.com/youtube/v3/commentThreads',
headers: {
'User-Agent': 'Request-Promise'
},
body: {
"snippet": {
"videoId": sourceId,
"channelId": comment_id,
"topLevelComment": {
"snippet": {
"textOriginal": comment
}
}
}
},
qs: {
part: 'snippet',
access_token: token
},
json: true
}, function (error, response, body) {
if (error) {
console.log('body', body);
console.log('error in when posting comment ', error.stack);
return reject(error);
}
return resolve(body);
});
});
I am having trouble updating a name in mongodb. The name is first saved by the user in a variable and passed into a function like this: putAjax(editName) Then it goes to the function here:
function putAjax(editName) {
$.ajax({
type: "PUT",
url: "/items/"+ editName,
data: editName,
dataType: 'json',
})
.done(function(result) {
console.log("result:", result);
console.log("data successfully saved:");
})
.fail(function(jqXHR, error, errorThrown) {
console.log(jqXHR);
console.log(error);
console.log(errorThrown);
});
};
I can console.log(result) and I can see the edited name so I assumed that the edit took place. Finally it makes the call to app.put on the server:
app.put('/items/:name', function(req, res) {
Item.find(req.params.name, function(err, items) {
if (err) {
return res.status(404).json({
message: 'Internal Server Error'
});
}
Item.findOneAndUpdate({
name: req.params.name
}, {
$set: {
name: req.params.name
}
}, { new: true },
function () {
res.json(items);
});
});
});
This is where the update doesn't seem to happen. When I use mongo shell, the one document I have still continues to have the same name and not the edited name. The confusing part is, why does console.log(result) show me the edited name then. I would really appreciate any help on this. Thanks.
You aren't passing a unique key to the database query. You're intention is to change the name stored in the database for an existing record but you're not doing this. Instead you are attempting to find a record that matches the new name value and you always return the value you have sent to the server.
Instead you need to pass a unique identifier with the AJAX request, using the URL makes the most sense.
function putAjax(id, editName) {
var payLoad = { name: editName };
$.ajax({
type: "PUT",
url: "/items/"+ id,
data: payLoad,
dataType: 'json',
})
.done(function(result) {
console.log("result:", result);
console.log("data successfully saved:");
})
.fail(function(jqXHR, error, errorThrown) {
console.log(jqXHR);
console.log(error);
console.log(errorThrown);
});
};
Server side code:
app.put('/items/:id', function(req, res) {
var data = req.body; // data should be validated
Item.findOneAndUpdate({ _id: req.params.id }
, { $set: data }
, { returnOriginal: false }
, function (err, result) {
if (err) {
return res.status(500).json({
message: 'Internal Server Error.'
});
}
return res.json(result);
}
);
});
My delete controller and AJAX Query are passing unexpected results in data.
I have the following in my AJAX request:
var endpoint = '/api/places/'+$(this).attr('id');
$.ajax({
method: 'DELETE',
url: endpoint,
dataType:"json",
data: $(this).serializeArray(),
success: deletePlace,
error: handleError
});
where endpoint is a valid URL and the same URL in my controller, shown here:
app.delete('/api/places/:id', function deletePlace(req, res) {
// remove place
db.Place.remove({ _id: req.params.id }, function(err, removePlace){
if (err) { throw (err) };
res.json(removePlace);
});
The data passed into deletePlace is "Object {ok: 1, n: 1}" when I am expecting it to be the JSON of the removed Place. Please excuse my novice but I have been wracking my brain on this. Have searched so many posts on here and still can't find the answer.
Only .remove will not return deleted document.
So You've to use .findByIdAndRemove method.
Please read api carefully: http://mongoosejs.com/docs/api.html#model_Model.findByIdAndRemove
Here is the fix:
app.delete('/api/places/:id', function deletePlace(req, res) {
// remove place
db
.Place
.findByIdAndRemove(req.params.id,
function(error, deletedDocument) {
if (error) {
return
res
.status(500)
.send({
success: false,
error: error,
data: {}
});
}
res
.send({
success: true,
data: deletedDocument
});
});
});