Cannot put error in rest api using node js - javascript

Hello I am trying to put the type value in my mongodb database using rest api. However, it shows an error saying cannot put (404 not found).
app.js
app.put('api/types/:_id', function(req,res){
var id = req.params._id;
var type = req.body;
Type.updateType(id, type, {}, function(err, type){
if(err){
throw err;
}
res.json(type);
});
});
type.js
module.exports.updateType = function(id, type, options, callback){
var query = {_id: id};
var update = {
name: type.name,
description: type.description,
category: type.category
}
Task.findOneAndUpdate(query,update, options, callback);
}

Use '/api/types/:_id' rather than 'api/types/:_id'

One more issue which causes the mentioned error:
Check if there is any typo mistake in the URL which you are trying to access.
In my case, I tried accessing
"/api/users/udpate/:id"
instead of
"/api/users/update/:id"
I have entered udpate instead of update.So express will not be able to find the route which causes this error.

Two solutions can be of this issue:
Can be a typo in endpoints.
Instead of this
"uesr/:userId"
Check for this
"/user/:userId"
Can be a slash missing in starting.
Instead of this
"user/:userId"
Add this slash in starting
"/user/:userId"

Related

How do I search for a data in the database with Node JS, Postgres, and dust js

I'm making a webpage with Node JS with dustjs and PostgreSQL. How do I make a search query in the html, so I can pass the value to the app.get
Do I need to use JQuery?
app.get('/teachers', function(req, res){
pool.connect(function(err, client, done){
if(err) {
return console.error("error", err);
}
client.query('SELECT * FROM teachers', function(err, result){
if(err){
return console.error('error running query', err)
}
res.render('teacherindex', {teachers: result.rows});
done();
});
});
});
app.get('/teachers/:str', (req,res)=>{
pool.connect((err, client, done) => {
if (err) throw err
client.query('SELECT * FROM teachers WHERE name = $1', [req.query.namesearch], (err, result) => {
done()
if (err) {
console.log(err.stack)
} else {
res.render('teacherindex', {teachers: result.rows});
}
})
})
})
This is my JQuery
$("#myBtn").click(function(){
var str = $("#myInput").val();
var url = '/teachers/'+str;
if(confirm('Search Record?')){
$.ajax({
url: url,
type: 'put',
success: function(result){
console.log('Searching');
window.location.href='/teachers';
},
error: function(err){
console.log(err);
}
});
}
});
My HTML
<input type="text" id="myInput" data-id="namesearch">
<button type="button" id="myBtn">Show Value</button>
Thank you!
FINAL ANSWER:
Ok so it turns out the issue you were having was something completely different. You are trying to use server side rendering for this, and I was showing you how to render the retrieved data on the client side.
I have forked, and updated your repo - which can be found at the link below..
Please review my changes and let me know if you have any questions.
Working repo: https://github.com/oze4/hanstanawi.github.io
Demo Video: https://raw.githubusercontent.com/oze4/hanstanawi.github.io/master/fake_uni_demo.mp4
EDIT:
I went ahead and built a repository to try and help you grasp these concepts. You can find the repo here - I tried to keep things as simple and understandable as possible, but let me know if you have any questions.
I had to make some minor changes to the paths, which I have commented explanations on the code in the repo.
I am using a "mock" database (just a JSON object in a different file) but the logic remains the same.
The index.js is the main entry point and contains all route data.
The index.html file is what gets sent to the user, and is the main HTML file, which contains the jQuery code.
If you download/fork/test out the code in that repo, open up your browsers developer tools, go to the network tab, and check out the differences.
Using req.params
Using req.query
ORIGINAL ANSWER:
So there are a couple of things wrong with your code and why you are unable to see the value of the textbox server side.
You are sending a PUT request but your server is expecting a GET request
You are looking for the value in req.query when you should be looking for it in req.params
You are looking for the incorrect variable name in your route (on top of using query when you should be using params) req.query.namesearch needs to be req.params.str
See here for more on req.query vs req.params
More detailed examples below.
In your route you are specifying app.get - in other words, you are expecting a GET request to be sent to your server.. but your are sending a PUT request..
If you were sending your AJAX to your server by using something like /teachers?str=someName then you would use req.query.str - or if you wanted to use namesearch you would do: /teachers?namesearch=someName and then to get the value: req.query.namesearch
If you send your AJAX to your server by using the something like /teachers/someName then you should be using req.params.str
// ||
// \/ Server is expecting a GET request
app.get('/teachers/:str', (req, res) => {
// GET THE CORRECT VALUE
let namesearch = req.params.str;
pool.connect((err, client, done) => {
// ... other code here
client.query(
'SELECT * FROM teachers WHERE name = $1',
// SPECIFY THE CORRECT VALUE
namesearch,
(err, result) => {
// ... other code here
})
})
});
But in your AJAX request, you are specifying PUT.. (should be GET)
By default, AJAX will send GET requests, so you really don't have to specify any type here, but I personally like to specify GET in type, just for the sake of brevity - just more succinct in my opinion.
Again, specifying GET in type is not needed since AJAX sends GET by default, specifying GET in type is a matter of preference.
$("#myBtn").click(function () {
// ... other code here
let textboxValue = $("#myTextbox").val();
let theURL = "/teachers/" + textboxValue;
// OR if you wanted to use `req.query.str` server side
// let theURL = "/teachers?str=" + textboxValue;
if (confirm('Search Record?')) {
$.ajax({
url: theURL,
// ||
// \/ You are sending a PUT request, not a GET request
type: 'put', // EITHER CHANGE THIS TO GET OR JUST REMOVE type
// ... other code here
});
}
});
It appears you are grabbing the value correctly from the textbox, you just need to make sure your server is accepting the same type that you are sending.

Handling error using request module - undefined object

I am trying to get coordinates of locations using Mapbox API via request module in my express app. URL of the request (specific location) is given through html form. It is parsed in the url and the API provides all the information, including coordinates. It looks like this:
app.post("/", function(req, res){
var location = req.body.location;
var url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + location + ".json?access_token=MY_TOKEN"
request(url, function(error, response, body) {
var data = JSON.parse(body);
var coordinates = data.features[0].geometry.coordinates
Everything works well if I try any location that an API can find and process. But when I tried inserting some random characters through the form the app crashes, giving the error "TypeError: Cannot read property 'geometry' of undefined". Console.log(data) shows that the features element of data object is an empty array [ ].
I tried handling the error by showing message and redirecting when data is undefied, like this:
if (!data.features) {
req.flash("error", "Location not found, please try again.")
res.redirect("/")}
Im at the beginning of my coding journey and this is my first request so I highly appreciate any help, thanks!
Sorry was off on my weekend.
If data.features is an empty array it won't fail the test (!data.features).
You could try something like
if(Array.isArray(data.features) && data.features.length>0){
//code here
}else{
req.flash("error", "Location not found, please try again.")
res.redirect("/")
}

How do I do a try/catch for my specific API Call example?

so my question is very specific. Whenever I run this bit from my page I get an error if I don't input the CORRECT ID I need to search for in the API. It doesn't know what to do when it doesn't make a valid API call because the query string is incorrect. How do I go about redirecting to a different page WHEN there's an error like that or how do I prevent it from STOPPING the program? I'm assuming there's a try catch in here but I tried it multiple different ways and I'm still confused because it doesn't work. Help please! I'm new to this... Here's the snippet. The request portion of the code is where the error occurs if the "bnetID" is not a valid ID. If it is valid it runs perfectly fine...
// Make a GET request to the /results page (When submit is pressed)
app.get("/results", function(req, res){
// Retrieve bnetID and REGION from the FORM
var bnetID = req.query.bnetID;
var region = req.query.region;
// Replace the # with a -
bnetID = bnetID.replace("#", "-");
// Create the query string
var url = "http://ow-api.herokuapp.com/profile/pc/"+ region +"/"+bnetID;
// Make the API request
request(url, function(err, response, body){
if(err){
console.log(err);
} else {
var playerData = JSON.parse(body);
playerData = findImportantData(bnetID, playerData);
checkIfExists(bnetID, playerData);
res.render("results", {data: playerData});
}
})
});
Why don't you handle what you want to do if there is an error?
if(err){
console.log(err); // change this to whatever you want to do
}

Mongoose Error: `{"message":"No matching document found.","name":"VersionError"}`

I've been trying to figure out why my HTTP Put has not been working after I use it once. When I click a button, I push the current user's id into an array like so:
$scope.currentUser = {
'eventsAttending' = [];
}
$scope.attending = function(event, id){
if($cookieStore.get('token')){
$scope.currentUser = Auth.getCurrentUser();
}
$scope.currentUser.eventsAttending.push(event._id);
$http.put('/api/users/' + $scope.currentUser._id, $scope.currentUser)
.success(function(data){
console.log("Success. User " + $scope.currentUser.name);
});
}
And my HTTP Put function is like so:
var express = require('express');
var controller = require('./user.controller');
var config = require('../../config/environment');
var auth = require('../../auth/auth.service');
router.get('/:id', controller.getEvents);
var router = express.Router();
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
User.findById(req.params.id, function (err, user) {
if (err) { return res.send(500, err); }
if(!user) { return res.send(404); }
var updated = _.merge(user, req.body);
updated.markModified('eventsAttending');
updated.save(function (err) {
if (err) { return res.send(500, err); }
return res.json(200, user);
});
});
};
In my HTML page I have multiple events I can attend, and each event has the button called Attend where I call $scope.attending and the function is called and the HTTP Put occurs. All of this works for the first event I choose to attend. However, when I click the Attend button for another event, I get an error that says:
{"message":"No matching document found.","name":"VersionError"}
And I have no idea why. The error occurs when I try to do updated.save() in the mongoose call and I get res.send(500, err)
I tried to look at http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html to solve the issue as I did some googling but I keep getting an error that says:
Undefined type at `versionKey`
Did you try nesting Schemas? You can only nest using refs or arrays.
Upon adding into my schema:
var UserSchema = new Schema({
versionKey: 'myVersionKey',
...
I also tried to change the .save() function into .update() as someone suggested it online but that seemed to give me even more errors. Any ideas how to fix this? That would be much appreciated!
I think the issue you may be experiencing (as was the case when I was getting this error from a similar action) is that after the first update, the '__v' VersionKey property on the newly updated document has changed, but you might not be updating that property on the object you have in the browser. So when you go to update it again, you're sending the old '__v' VersionKey, (even though you updated the 'eventsAttending' property) and that document conflicts the newer VersionKey. This would assume that the Auth.getCurrentUser(); function returns the whole document object from mongo.
What I did to fix this was simply add delete entity.__v; to delete the old VersionKey from the document before sending it with the request. Better yet, I'd recommend updating the properties your API sends back when returning documents so this issue doesn't happen in the first place.

Using the PUT method with Express.js

I'm trying to implement update functionality to an Express.js app, and I'd like to use a PUT request to send the new data, but I keep getting errors using PUT. From everything I've read, it's just a matter of using app.put, but that isn't working. I've got the following in my routes file:
send = function(req, res) {
req.send(res.locals.content);
};
app.put('/api/:company', function(res,req) {
res.send('this is an update');
}, send);
When I use postman to make a PUT request, I get a "cannot PUT /api/petshop" as an error. I don't understand why I can't PUT, or what's going wrong.
You may be lacking the actual update function. You have the put path returning the result back to the client but missing the part when you tell the database to update the data.
If you're using MongoDB and ExpressJS, you could write something like this :
app.put('/api/:company', function (req, res) {
var company = req.company;
company = _.extend(company, req.body);
company.save(function(err) {
if (err) {
return res.send('/company', {
errors: err.errors,
company: company
});
} else {
res.jsonp(company);
}
})
});
This mean stack project may help you as it covers this CRUD functionality which I just used here swapping their articles for your companies. same same.
Your callback function has the arguments in the wrong order.
Change the order of callback to function(req, res).
Don't use function(res, req).
Also if you want to redirect in put or delete (to get adress), you can't use normal res.redirect('/path'), you should use res.redirect(303, '/path') instead. (source)
If not, you'll get Cannot PUT error.
Have you been checking out your headers information?
Because header should be header['content-type'] = 'application/json'; then only you will get the update object in server side (node-express), otherwise if you have content type plain 'text/htm' like that you will get empty req.body in your node app.

Categories

Resources