Trouble sending AJAX GET request to mongodb - javascript

I am currently trying to display data from a mongodb collection on the browser using nodejs and express and am having a very tough time with it. Here is the call itself on the clientside.
document.onload= $(function (e) {
var i = 0;
$.ajax({
type: "GET",
url: "http://localhost:3000/viewdata",
dataType: "jsonp",
jsonp: 'jsonp',
success: function (responseData, status) {
//code doing things with the data
}
Here is whats going on in node.
app.post('/viewdata', function(req, res){
tweets.find({}, function (err, doc) {
res.render('../../views/view.html', doc);
});
});
The call is returning "200 OK". I was able to view the data from mongo on the console so I know the data is there, I am not sure how to get to it and display it on the browser though. Thanks for the help

For anyone looking for the answer to this question, the problem is that I am trying to get data from the server in a post request. I made a separate GET request below the POST request and sent the data to the view. You can now use an ajax get request and use the data on the client-side.
app.get('/viewdata', function(req, res){
tweets.find().toArray(function(err, items) {
/*console.log(items);*/
res.send(items);
});
});
And on the clientside:
$.get("/viewdata", function(data) {
/*do stuff with the data*/
}

Related

Why does my JSON file from my express server not download when I request with ajax?

I would like to set up my express server such that I can get the browser to prompt the user to download a JSON file when I send an Ajax GET request. I am able to get the file to download when I request a test route from the browser bar, but when I send the request from Ajax, it won't download, though the request returns 200 and I can see the contents of the file when I look in dev tools.
In the process of trying to get it to work, I thought maybe Express's res.download() function required a GET request, so I set it up so that the first request is a POST that sends the JSON data and gets the filename back, and then sends the filename as a parameter in the GET request.
Any help is greatly appreciated and I would be happy to provide more information if necessary.
Here is the code for the download route:
app.get("/generated-files/download/:file", function(req, res){
const fileName = req.params.file;
console.log(fileName);
const filepath = path.join(__dirname, 'generated-files', fileName);
res.download(filepath, fileName, function(err){
if(err){
console.log(err);
}
/*
fs.unlink(filepath, function(err){
if(err){
console.log(err);
}
});*/
});
});
Here is the test route:
app.get("/download-test", function(req, res){
res.download(path.join(__dirname, 'generated-files', '01a6cbe0-ce2d-11ea-86bc-092eb628bcba.json'), '01a6cbe0-ce2d-11ea-86bc-092eb628bcba.json');
});
And here is the Ajax request:
//begin first ajax request
$.ajax({
contentType: 'application/json',
data: JSON.stringify(serializedCharacter),
success: function(ret){
console.log("Response Received:");
console.log(typeof ret + ":" + ret);
// begin second ajax request
$.ajax({
method: 'GET',
url: '/generated-files/download/' + ret,
success: function (ret){
console.log("delete successful");
},
error: function (jqxhr, ts, err){
console.log("something is wrong in delete");
console.log(jqxhr);
console.log("\n"+ts);
console.log("\n"+err);
}
});
// end second ajax request
},
error: function(jqxhr, textStatus, errorThrown){
console.log("Something is not right");
console.log(jqxhr);
console.log("\n"+textStatus);
console.log("\n"+errorThrown);
},
method: 'POST',
url: '/generated-files'
});
//end first ajax request
EDIT:
OK, so I figured something out. I replaced the second Ajax request with this line:
document.location.href = '/generated-files/download/'+ret;
I suspect the problem was the Accept request header. The default Ajax Accept header is */*, while both the browser bar and aforementioned line had an Accept header of text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8. I may be wrong, in fact I am doubting this somewhat because I was under the impression that */* was supposed signal that the requestor would accept a response of any content type. If anyone could confirm this, or tell me why I am wrong, I would appreciate it greatly.
Ajax purpose is updating a part of web page without reloading the page, using the response data provided by server side app as json or xml. Here the response data will come back to the page itself, and can be used to render the page contents.
In downloading and page redirection the control goes out of the page. So this is
not an Ajax use case.We can achieve those directly using plain javascript as you mentioned in the final section of your description.
For downloading the file your approach is correct by using
document.location.href= url
alternatively we can use
window.location = url
For page redirection we can achieve by
window.location.href = url

Creating routes for Ajax calls in NodeJs

let's say I have this route for my rendered HTML:
app.get('/profile/:id', function (req, res) { // my route
res.render('profile', { id: Number(req.params.id) }); // render the file and set a variable
});
and in my client side javascript file for the profile page I want to get data from the server. I request the data when loading the page by sending a user id to the server and the server returns a user object:
$(document).ready(function() {
var user = null;
$.ajax({
type: 'GET',
url: '', // This one is missing here
dataType: 'json'
}).done(function(data){
user = JSON.stringify(data);
});
console.log(user.name);
});
And my server would handle this function:
app.get('', function (req, res) { // missing route
var userId = ; // This is missing
var userObj = getUserById(userId);
res.send(userObj);
});
What route do I have to use? Tutorials say I have to pass in the route like /profile/:id but this route already exists?
I tried defining a new route like:
app.get('/reqUser/:id', function (req, res) { // Ajax route
res.send(getUserById(Number(req.params.id)));
});
and for my Ajax call I pass in the url http://localhost:8888/reqUser/12345 but this seems to be wrong because user is still null after using the Ajax call.
So how can I define a route handling the page and the Ajax call?
Edit: First off, you'll want to fix the bug in your client-side JS, where you are attempting to print user.name before user has been fetched from the server. You can fix this by moving your console.log statement into the done() callback like so:
$(document).ready(function() {
var user = null;
$.ajax({
type: 'GET',
url: '', // This one is missing here
dataType: 'json'
}).done(function(data){
user = JSON.stringify(data);
console.log(user.name); // log here
});
});
Regarding your routes question, you have several options. Below are two common solutions to this problem:
Create a separate api route to distinguish your API requests from your page requests. For example, app.get('/api/profile/:id, (req, res) => {...});'
Add a URL parameter to your AJAX calls specifying the format you want the response to be in, with the default being the page's HTML. For example, your AJAX would send a GET request to the URL /profile/2012?format=json, which would return the profile's information in JSON.
Personally, I prefer the first option, as it makes intent more clear.

How to delete data from mysql database with angularjs $http request?

Here is the code
$scope.Delete = function(customer ){
$http({
method: 'get',
url: 'rest/customers',
data: {customers:customer.custId},
}).then(function successCallback(response) {
$scope.customers.splice($scope.customers.indexOf(customer), 1);
});
}
If I call this function it only deletes the data from the front-end. The data is not getting deleted from mysql table. Can anyone help me with this.
//try like this..sure it will work
$http.delete('your url' + id).then(function(result){
if(result.data){
//your handle code
}
}, function(err) {
console.log(err);
});
First, it is not efficient to test api with front end code, you need to set up a postman test to separate your concern, get it working in postman first.
After postman test, you can use $http.delete, sample link is here

Putting live score from database using AJAX and jQuery

So I'm having a database which gets updated after getting score of a match.
Right Now I'm able to make ajax get request to my route for getting the latest score from database on $(document).ready(function() and change my html to show score but it is static and does not gets updated.
So my question is how to make this ajax request in a loop. Right now a user has to refresh to make the request again and get the updated latest score.
I am using mongoose, mongodb, nodejs on express framework, and jquery for scripts.
This is my nodejs route for handling ajax request, it returns json of match data
router.get('/matchData',function(req,res){
Match.getMatchData(function(err,match){
if(err) throw err;
res.send(match);
});
});
This is my script for AJAX.
$(document).ready(function(){
$.ajax({
type: 'GET',
url: 'http://localhost:3000/matchData',
dataType: 'json'
})
.done(function(data) {
$('.team1').text(data.title);
$('.team1odds').text(data.values.t1odds);
$('.team1probability').text(data.values.t1probability);
$('.team1score').text(data.values.t1predict);
$('.team2').text(data.title);
$('.team2odds').text(data.values.t2odds);
$('.team2probability').text(data.values.t2probability);
$('.team2score').text(data.values.t2predict);
})
.fail(function() {
alert("Ajax failed to fetch data")
});
});
There are multiple ways to do this, the easiest would be to use long polling, but it is also the most ineffective.
Very simple example:
var seconds = 5;
setInterval(function runner() {
// run your ajax call here
var result = callAjax();
}, seconds * 1000);
A much better way would be to use websockets, as the score gets updated server-side you push the event to the client.

jQuery + node.js express POST request

I'm trying to send a post request to a node server.
This is my client-side code:
function send(userid,message){
$.ajax({
method: "POST",
url: "/chat/messages?id="+userid+'&message='+message
})
clear();
}
This is my server side code:
app.post('/chat/messages',function (req,res){
var query = url.parse(req.url,true).query
insertMessage(query.id,query.message)
})
This works, however I'm not sure getting data in the query string using post is the right way to go.
I tried adding a data field in $ajax parameter:
function send(userid,message){
$.ajax({
method: "POST",
url: "/chat/messages"
data : {'id' : userid, 'message' : message}
})
clear();
}
And using bodyParser() in the server end to parse the body contents:
app.use(bodyParser.json())
app.post('/chat/messages',function (req,res){
console.log(req.body)
})
but when I log the response, the body{ } object is always empty.
Why is that?
Is a <form> tag necessary for POST requests?
I tried editing my ajax request to use json as the dataType and stringifying the data, but the req.body is still empty.
$.ajax({
method: "POST",
url: "/chat/messages",
data : JSON.stringify({'id' : userid, 'message' : message}),
dataType: 'json',
})
When you post data to a server, the data is usually urlencoded and added to the body of the request. In your example, it would look like this:
id=<userid>&message=<message>
Therefore, the bodyparser you need to be able to parse that is bodyparser.urlencoded()
app.use(bodyParser.urlencoded())
Note that it isn't always urlencoded, it all depends on what you are using to send the post. AngularJS for example defaults to sending it as json instead. The good news is you could simply add both bodyparsers and your route won't need to know which method was used since in both cases the data would end up on req.body with key/value pairs.
You should read the express documentation. http://expressjs.com/api.html#req
// For regular html form data
app.use(bodyParser.urlencoded())
app.post('/chat/messages',function (req,res){
console.log(req.body);
console.log(req.query.id);
console.log(req.query.messages);
})
You can also do req.params
app.post('/chat/messages/:id',function (req,res){
console.log(req.body);
console.log(req.query);
console.log(req.params.id)
})

Categories