Why my router.post() allow just one operation? - javascript

I'm working in a web project and I have a litle problem in my back-end side
I'm sending data from front-end to back-end, and then make two operations :update the JSON file which is in a directory, and at the same time save the data in MongoDB, but only updating the JSON file works, I have to make as comment the updating code to see the data in MongoDB ,
Here is my code :
router.post('/', (req,res)=>{
console.log(req.body);
var toSaveDb={
name:req.body.name,
age:req.body.age,
}
// operation 1 : save the imported data in MongoDB
let mdata=new MachineData(toSaveDb);
console.log(mdata);
mdata.save();
// operation2 : update the JSON file with imported data
fs.writeFile('C:/path/to/file',
JSON.stringify(toSaveDb),err=>{
if(err){console.error(err);return;};
});
});
module.exports=router;
Any help would be appreciated

Looks like just a bug in the arguments to fs.writeFile. Change this:
fs.writeFile('C:/path/to/file'),
JSON.stringify(toSaveDb),err=>{
if(err){console.error(err);return;};
});
to this:
fs.writeFile("C:/path/to/file", JSON.stringify(toSaveDb), (err) => {
if (err) {
console.error(err);
return;
}
});
Now it's correct, and Prettier.

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.

How do I display response data in the front end?

I've made GET requests to the github API:
axios.get('https://api.github.com/users/roadtocode822')
.then(function (response) {
console.log(response.data);
})
I get the response data. This function lives in the app.js file.
Also lives on the app.js file is the following code:
app.get('/', function(req, res){
Article.find({}, function(err, articles){
if(err){
console.log(err);
} else {
res.render('index', {
title: "Articles",
articles: articles
});
}
});
});
I'm able to query data from my mongodb database through the Article.js mongoose model and send the data to my index.pug file.
I want to be able to take the GITHUB response data and also render it in one of my pug view files. I feel like I'm missing some sort of concept in Javascript that's preventing me from achieving this.
Thanks in advance.
To get the Github response as a JSON, just use JSON.parse(). You won't be able to use your .pug template on the front end, however. That template is interpreted on the server side and is sent from server to client as plain old HTML. If you're interested in front-end templating, check out something like handlebars.js.
axios.get('https://api.github.com/users/roadtocode822')
.then(function (response) {
console.log(response.data);
})
from the code above, response.data will be a html content because your server returns res.render.
in the front-end, you should use a tag and form post instead of ajax call like this
Click

Node.js: Returning proper JSON from mongoose query

I have this express application with mongoDB as the database and handlebars as my server-side templating engine. I am not using AngularJS or Ajax in my application.
In one of the routes, I have to render the page as well as send over a json file from the database. However, I am not able to achieve this.
Here is code snippet the my route:
router.get('/disks', function(req, res, next) {
places.find({"category": "disks"}, function(err, disks){
if(err){
throw err;
}
res.render('disks',
{
'risime': JSON.stringify(disks)
});
console.log(disks); // PROPERLY LOGS TO THE CONSOLE
});
});
In the hbs, I am trying to capture it, but I don't even think that it is JSON.
Here is how it gets logged in the client side:
[{"_id":"5704630a7d4cd367f8dsdce7","name":"Seagate",:"This awesome Hard disk",","categories":["SDD","256GB"]}]
What is the issue and how do I resolve it?
It's handlebars that "html escapes" your string (which is what you normally want).
if you don't want that, you can use the "triple-stash" notation, like this:
{{{risime}}}
You can read about this here: http://handlebarsjs.com/#html-escaping
I think you need to add this before render:
res.type('application/json');
The client will know this is a JSON, not a HTML or a plain text and it will be shown correctly.
I hope my answer will help you.

Update a JSON file in AngularJS

I've got some data from a JSON file, which I use in my HTML getting it first from AngularJS like this:
$http.get('js/data.json').success(function(data) {
$scope.data = data;
});
And I want to update this JSON file after clicking a button in the HTML:
<button ng-click="postData(id)">Post</button>
You cannot write on files via JavaScript only (AngularJS).
You are to go via server side and point your "post" request to a server side script (i.e: PHP) and make that script do the job.
This sort of thing won't work. The file you are trying to write to would be on a server; and as it is right now, it would be a static resource. I'd suggest reading up on Angular resources, here. You can set up your server-side code to perform CRUD operations on the json file, but an actually database would be best. If you prefer to use a json format, Mongodb is your best choice; here is a link to Mongodb University, which offers free courses. I've done it in the past, and it's been great.
Now, for some actually help in your situation:
You can perform a GET request on your json file because it's seen as a static resource. The POST request, however, needs server-side scripting to do anything.
$http.get('api/YOUR_RESOURCE').success(function(data) {
$scope.database = data;
});
$http.post('api/YOUR_RESOURCE', {
data_key: data_value,
data_key2: data_value2
}).success(function(data) {
data[id].available = false;
});
This may be further ahead on your path to learning Angular, but here is a snippet of Node.js server code, with a Mongo database and Mongoose to handle the 'Schema', to help you get an idea of how this works:
var mongoose = require('mongoose'),
YOUR_RESOURCE = mongoose.model('YOUR_RESOURCE');
app.route('/api/YOUR_RESOURCE')
// This should be your GET request; 'api/
.get(
// Get all docs in resource
YOUR_RESOURCE.find().exec(function (err, data) {
if (err) {
return res.status(400).send({
message: SOME_ERROR_HANDLER
});
} else {
res.json(data); // return list of all docs found
}
});)
// Add new doc to database
.post(function (req, res) {
// The keys of the object sent from your Angular app should match
// those of the model
var your_resource = new YOUR_RESOURCE(req.body);
your_resource.save(function (err) {
if (err) {
return res.status(400).send({
message: SOME_ERROR_HANDLER
});
} else {
// returns newly created doc to Angular after successful save
res.json(your_resource);
}
});
);
Here is an SO page with a list of resources on getting started with Node; I recommend Node because of it's ease of use and the fact that it is written in JS. The Mongo University lessons also go through setting up you server for use with the database; you can choose between several flavors, such as Java, .NET, Python or Node.
There is a bit left out in the examples above, such as the Mongoose model and Node setup, but those will be covered in the resources I've linked to on the page, if you choose to read them. Hope this helps :)

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