Basically what I wantto achieve is a searchable/filterable listview
so far I'm able to fetch some data from a database and have express with pug render me a page showing the results in a listview.
Now I want to add the functionality of filtering the displayed listview.
Therefore on every keyup event within a textbox I make an AJAX post request to the server sending the query string from the textbox. So far everything works just fine, but when i try to "re-render" the page with the filtered resultset nothing happens in the browser.
My routes look like this:
var rechnungen;
router.get('/', function(req, res) {
connection.query('SELECT * FROM rechnungen ', function(err, result) {
rechnugen = result;
res.render('rechnungen', {rechnungen: result});
});
router.post('/:query', function(req, res) {
console.log("received ajax request");
console.log("with query " + req.params.query);
res.render('rechnungen', {rechnungen: {}});
});
initially the query statement fetches the data and res.render works just fine, when I make the AJAX call everything seems to work as well (the console log output matches my input) but regardless what i try to pass to the view (res.render) in the post route nothing happens.
Is it not possible to "re-render" a view or is there any other conceptional misstake I make?
thanks for your help
AJAX POST call is not a traditional HTTP call.
The rendered page sent from the server will come in the response object of success handler of your AJAX call.
So, either
replace whole HTML with the response HTML, or
make a traditional HTTP form POST, in that case the browser by-default renders the response of the server.
Related
As the title says, i have a part of my react app that tries to get some data from my database, making a select based on the value I passed to it. So im gonna go ahead and first show the code where i think the problem lies:
So first, this is the function from one of my forms that sends the request to the server, i know code is probably ugly, but i can tell from the console.logs that the parameters im sending are what i intend to send(a string called "licenciaInput"
async handleClickLicencia (event) {
event.preventDefault();
console.log(this.state);
console.log("licenciaInput: "+this.state.licenciaInput);
const datoBuscar = this.state.licenciaInput;
axios.get('http://localhost:3001/atletas/:licencia',this.state)
.then(response =>{
console.log(response)
})
.catch(error =>{
console.log(error)
})
And then, i have this function which is called in that localhost route which attempts to get "licencia", and launch a select in my postgresql db where licencia="whatever", you can see the sentence in the code:
const getAtletasByLicencia = (request, response) => {
const licencia = request.body.licenciaInput;
console.log("Request: "+request);
console.log("what the server gets: "+licencia);
// const licencia = request.licenciaInput;
const sentencia ="SELECT * FROM atleta WHERE licencia ='"+licencia+"'";
pool.query(sentencia, (error, results) =>{
if(error){
throw error
}
response.status(200).json(results.rows)
})
}
As you can see, i have console.logs everywhere, and i still cannot access whatever element i send, because i always get on the server console "undefined" value.
TLDR:How can i access the "licenciaInput" i passed from my client form to my server, i have tried request.body.licenciaInput, request.params.licenciaInput, and request.licenciaInput, but none of those seem to work
I also know i have to treat after that the data i receive from the server, but i need to solve this before looking two steps ahead. Im also really new to React and node/express, so feel free to burn me with good practices im not meeting.Thanks in advance
EDIT: Im also adding this code that i have which shows the route for my method in the server:
app.get('/atletas/:licencia', db.getAtletasByLicencia)
As #Gillespie59 suggested that i should send a POST request, but i dont think i should if im both trying to send a parameter to the server to make a select, and then send the results back to the client
Change your request to:
axios.get(`http://localhost:3001/atletas/${this.state.licenciaInput}`)
...
and your route (if you are using express) should look like this:
app.get('/atletas/:licencia', function (req, res) {
var licencia = req.params.licencia
...
})
As you are using request.body you should send a POST request with axios and add a body.
So I'm using sequelize for a simple CRUD style webpage. My issue is I am able to send the data typed into an input field to mysql workbench and it's stored in the table but on the webpage itself nothing happens.
//uses var=Posts which contains the fields userName
//and userPosts in my database
var db = require("../models");
// route to create posts
app.post("/api/posts", function(req, res) {
console.log(req.body);
db.Posts.create({
userName: req.body.username,
userPosts: req.body.user_post,
})
.then(function(dbPost) {
res.redirect('/dashboard');
res.json(dbPost);
});
});
Thanks in advance for any help!
webpage itself nothing happens
What page? Your successful db action is telling the app to redirect to /dashboard but you're also trying to send JSON data. I'm surprised you're not getting header errors in your app. You can't redirect to another route and send data to the client at the same time.
You would need to redirect to /dashboard and then your dashboard route would have to query the data again to be returned for display.
I think the problem here is that you both issue a res.redirect() at the same time as doing res.json(). Pick one of them.
I will demonstrate my problem with this simplified code:
app.get('/test', (req, res) => {
let x = req.query.someVar;
app.post('/test', (req, res) => {
console.log(x);
});
res.send(`Hello ${req.query.someVar}`);
});
The first time this code runs, the POST callback function saves a reference to x which is whatever I pass as query parameters. if I change the query parameters, send another GET request it will be updated in the server's response i.e.res.send(Hello ${req.query.someVar}); but a POST request will still log the original x value to the console.
Why is it behaving this way? I have tried many things like passing by objects and through other functions, etc..
I am familiar with how closures work, but obviously not entirely as this is most definitely a problem with the POST call back preserving the value of the query parameters and not updating them.
Thanks.
I'm not sure what you are trying to do. No one defines a POST inside of a GET, they do that at the root level, unless you want the GET request to change the behavior of your server. app.post means 'add a new route to handle a POST'. Perhaps you wanted to actually send an HTTP request from the GET handler?
If you want the behavior to change maybe just handle the POST at the root level and set a global flag in the GET handler to indicate that POST should do something different with subsequent requests.
I am trying to determine if i can call res.send(data) and then res.render('reports') simultaneously.
To explain further in detail, when i route to '/reports', first on my server side i making a REST call to an API which returns back json data. Now i want this json data to be accessed on the client, for which i am making an ajax call from my javascript. Hence the use of res.send(), but i also want to render the page in this call
So it looks like the following on my server side code
router.get('/reports', function(req,res){
//Making the REST Call to get the json data
//then
res.send(json);
res.render('reports');
});
Every time i hit the '/reports' on the browser, I see the json value instead of the page being rendered and my console throws an Error: Can't set headers after they are sent.
You could use content negotiation for that, where your AJAX request sets the Accept header to tell your Express server to return JSON instead of HTML:
router.get('/reports', function(req,res) {
...
if (req.accepts('json')) {
return res.send(theData);
} else {
return res.render('reports', ...);
};
});
Alternatively, you can check if the request was made with an AJAX call using req.xhr (although that's not 100% failsafe).
No you can't do both, but you could render the page and send the data at the same time:
res.render('reports',{data:json});
and then access those data in the newly rendered page.
alternatively you could send a flag when making the call , and then decide whether you want to render or send based on this flag.
Ideally, it needs to be 2 separate route, one spitting json and other rendering a view. Else, you could pass a url param, depending on which you return json or render a view.
router.get('/reports/json', function(req,res){
var data = JSON_OBJECT;
res.send(data);
});
router.get('/reports', function(req,res){
var data = JSON_OBJECT;
res.render('path-to-view-file', data);
});
No, you can't. You can only have a single response to a given request. The browser is either expecting an HTML document or it is expecting JSON, it doesn't make sense to give it both at once.
render just renders a view and then calls send.
You could write your view to output an HTML document with a <script> element containing your JSON in the form of a JavaScript literal.
I am trying to create a page to display all the forum posts...everything works fine, but I notice that after I create a post (when it redirects to show all of the posts) - in firebug, the post call hangs for a very long time. However, the data gets sent through, even though it looks like the post call is still pending...because it shows up on the page with all of the posts, that gets loaded right after. This is how I am doing it now.
post controller (post.js):
'use strict';
angular.module('appApp')
.controller('PostCtrl', function ($location, $scope, $http) {
$scope.errors = {};
$scope.post;
$scope.postit = function(form) {
$scope.submitted = true;
if(form.$valid) {
console.log($scope.post.posttitle + " this is $scope.post");
$http.post('/api/post', $scope.post).success(function() {console.log("no errors whoohoo")});
$location.path('/forum');
}
};
});
As you can see, right now, I am executing the redirect ($location.path) after the post call line. The redirect works fine like this...however - if I try to put the redirect in the success function:
$http.post('/api/post', $scope.post).success(function() {$location.path('/forum'); console.log("no errors whoohoo")});
the redirect never happens, and it just hangs on the post call. Does anyone know what is going on? I think the post call should only take a few ms to complete (it is just storing a post title, and content).
The post call hangs regardless of which way I do it...it's just the second way doesn't redirect the page.
UPDATE
As suggested in the comments, something is wrong with my server side code - I may have isolated the problem.
This is the function that gets called when I want to list all the posts on the page (api.js):
exports.posts = function(req, res) {
return Post.find(function (err, posts) {
if (!err) {
console.log(posts + " server side posts function route");
return res.json(posts);
} else {
return res.send(err);
}
});
};
The console.log message never appears, so this must be where it is getting hung up...any ideas?
The area of code that calls this function looks like this:
app.route('/api/post')
.get(api.posts);
It is one of my express routes.
It turns out that using $location.path('/xxx') wasn't enough, I needed to also use res.redirect on the express side for the redirect to actually work. (Had to use both).