Cant get view to render - node.js

I am developing an application with node.js, express, couchDB and using nano to communicate with couch.
I am using a jquery get request from client javascript. Using fiddler i can see that i get my view in the RAW result but the view is never rendered.
client:
$.get('employee/'+customerId, function(data){
return;
});
route:
app.get('/employee/:id', employee.viewEmployee);
viewEmployee:
exports.viewEmployee = function(req, res){
db.get(req.params['id'], { revs_info: false }, function(err, body, header) {
res.render('employee/single', {employee: body});
});
};
Everything works with no errors and i get the 'employee/single' view html in the raw response. my question is why the view is not rendered? why is the html just sent back in the raw and how can i get this to work?

Your $.get call is using a call back that isn't doing any thing.
from the jQuery api examples
$.get("test.php",
function(data){
$('body').append( "Name: " + data.name ) // John
.append( "Time: " + data.time ); // 2pm
}, "json");
Shows you how to do this.

You are doing an ajax call.
try console.log(data) inside your $.get callback, are you seeing the html you expect?

Related

Error: Can't set headers after they are sent - Ajax, Node, Express

I'm trying to using Airtable, node.js, express.js and jquery to create a simple user authentication functionality but I'm fairly new at this and I'm running into a problem I can't seem to fix and the articles I've read I can't seem to grasp or adapt to my particular situation.
I have this Ajax call in my html doc:
$("#checkUser").submit(function(e) {
var studentID = $('input[name="student"]').val()
e.preventDefault(); // avoid to execute the actual submit of the form.
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: form.serialize(), // serializes the form's elements.
success: function(data) {
$(window).attr("location", window.location.href + 'Dashboard?student=' + studentID);
},
error: function(data){
console.log("User not found. Try again");
}
});
});
This call sends the inputted username and data to the server which then processes it in the following way:
app.post('/checkUser', urlencodedParser, function(request,response){
var user = JSON.stringify(request.body);
user = JSON.parse(user);
base('RegisteredStudents').select({
filterByFormula: '{UserID} = ' + user.student,
view: "Grid view"
}).eachPage(function page(records, fetchNextPage) {
records.forEach(function(record) {
response.sendStatus(200);
});
fetchNextPage();
}, function done(error) {
response.sendStatus(404);
});
});
If the user exists in the database of Airtable, it should send '200' which the Ajax then reacts by redirecting accordingly to the user's profile. Otherwise, if the user does not exist, the server should respond with '404', which the Ajax call should react to by printing a statement in the console. While it does do these two things well, the server breaks down when, after a student puts in the wrong user ID and the Ajax prints the statement, the student tries to put once more a userID. I get the " Can't set headers after they are sent. " message. Please, how can I solve this?
Thank you!
You have two response.send..., you can only send data once. Either make sure only one runs with some conditional or add return before all response.send... so if any of them runs, the program will return and the other response.send.. will not run.

Node, Express, Ajax, Form Submission

Help, I'm Stuck! I am playing with a CRUD setup with Node Express but with AJAX post request. I have the read form working fine.
The form has one input filed which is a lookup email. AJAX post the form data with the following code
if ($("#rsvp-search-form").length) {
$("#rsvp-search-form").validate({
rules: {
...
},
messages: {
...
},
submitHandler: function (form) {
$("#loader").css("display", "inline-block");
$.ajax({
type: "POST",
url: "/",
data: $(form).serialize(),
success: function (data, textStatus, jqXHR){
if (typeof data.redirect == 'string')
window.location = data.redirect;
}
,
error: function() {
$( "#loader").hide();
$( "#error").slideDown( "slow" );
setTimeout(function() {
$( "#error").slideUp( "slow" );
}, 5000);
}
});
return false; // required to block normal submit since you used ajax
}
});
}
I have a express post route to '/' that returns a status with res.status(#).send() and the proper success/error block is executed based on the whether status # is 400 or 200.
Now on the update form I have the same basic setup with many more form inputs, but the AJAX code does not process the res.status(#).send() response by executing the proper success or error block, instead it is just loading a new page with the same url as the request was processed from.
The AJAX code request is similar to the top with difference of url:
submitHandler: function (form) {
$("#loader").css("display", "inline-block");
$.ajax({
type: "POST",
//The website when loaded has an invitation
//object that is passed by express
url: "/rsvp/" +invitation._id,
data: $(form).serialize(),
dataType: 'application/json'
I verified that the proper post route is running and receiving the invitation._id. It returns res.staus(#).send() but the ajax does not process the success or error block it just redirects to the requesting url but does not actually render the url.
I don't know if it is just that the form is still processing the default action, if the response from express is not correct, etc etc
I hope I have been clear on my issue and someone knows what I am doing wrong here.
Regards!
Update!
I got it working. Though the url with variable was correct and express was receiving the proper id, JS was throwing an error causing everything to crash. I never caught the error because the page would reload to the blank page and clear the console. I fixed it by saving the id in a hidden field when rendering the form and used that instead. Seems to have fixed the problem.
Thanks for looking!

Send variable from mongoose query to page without reload on click

I have a link on my site. When clicked it'll call a function that does a mongoose query.
I'd like the results of that query to be sent to the same page in a variable without reloading the page. How do I do that? Right now it is just rendering the page again with new query result data.
// List comments for specified chapter id.
commentController.list = function (req, res) {
var chapterId = req.params.chapterId;
var query = { chapterId: chapterId };
Chapter.find({ _id: chapterId }).then(function (chapter) {
var chapter = chapter;
Comment.find(query).then(function (data) {
console.log(chapter);
Chapter.find().then(function(chapters){
return res.render({'chapterlinks', commentList: data, user: req.user, chapterq: chapter, chapters:chapters });
})
});
})
};
You just need to make that request from your browser via AJAX:
https://www.w3schools.com/xml/ajax_intro.asp
This would be in the code for your client (browser), not the code for your server (nodejs).
UPDATE:
Here's a simple example, which uses jQuery to make things easier:
(1) create a function that performs and handles the ajax request
function getChapterLinks(chapterId) {
$.ajax({
url: "/chapterLinks/"+chapterId,
}).done(function(data) {
//here you should do something with data
console.log(data);
});
}
(2) bind that function to a DOM element's click event
$( "a#chapterLinks1" ).click(function() {
getChapterLinks(1);
});
(3) make sure that DOM element is somewhere in you html
<a id="chapterLinks1">Get ChapterLinks 1</a>
Now when this a#chapterLinks1 element is clicked, it will use AJAX to fetch the response of /chaptersLink/1 from your server without reloading the page.
references:
http://api.jquery.com/jquery.ajax/
http://api.jquery.com/jquery.click/

submitting form data without leaving page. Express, Node.js, Pug

I read through a similiar post but the individual was using perl and something elss so it didn't help me. My question is how can i submit a form with node js/pug but remain on the same page.
In the pug form the method is set to POST and action set to /profile
in my nodejs i'm using
router.post("/profile", req, res, next){
return res.redirect("back")
}
The problem is that all this does is reload the page. I want to stay on the page and simple show a message saying "profile update".
Then don't return a redirect. Simply take the post data and process it, you can return the state of the operation, for example. Then however you should use an AJAX query instead of stock form, which will always redirect you to the action URL.
router.post("/profile", req, res, next){
return updateProfile(req.body); // true or false
}
And in jQuery, for example, you can perform an AJAX request
$.ajax({
type: "POST",
url: "/profile",
data: profile_form_data_object,
success: function(data) {
alert("Result of the profile update was: " + data);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Refresh section of a page using EJS and Express

I have a checkbox that when pressed call a function that does a GET request. Based on the selection I want to display extra checkboxes on the same page. At the moment this is the code I have so far:
Client side
function selectedHouse(house)
{
if(house.checked){
$.get('/', {data: house.value});
}
}
Server side
var routing = function (nav, houses) {
router.route('/')
.get(function (req, res) {
var rooms = [];
rooms = getRooms(req.query.data);
console.log(rooms);
res.render('index', {
title: 'Independent cleaner',
nav: nav,
houses: houses,
roomsForHouse: rooms
});
});
return router;
};
The first time the page loads, it loads with the correct title, nav and houses. When the function is executed on client side, I get back the related rooms for the house and I'm trying to populate the roomsForHouse variable which I'm displaying on the view.
The problem is that the view doesn't render the roomsForHouse variable. So the GET request is called once the page loads and a second time when the function executes. Can this be achieved?
It's a bit more complex. You'll need to use ajax for this. EJS is server side templates (as you are using them) so you'll want to use jQuery to make the call and update your already rendered page.
Server
Your server will need a route that delivers JSON data. Right now you are rendering the entire page. So:
app.get('/rooms/:id', function (req, res) {
// Get the house info from database using the id as req.params.id
...
// Return the data
res.json({
rooms: 2
...
});
});
Client
Using jQuery make a call to your json route once the user selects the house.
function selectedHouse(house)
{
if(house.checked){
// Pass some identifier to use for your database
$.ajax({
type: 'GET',
url: '/rooms/' + house.id,
success: function(data) {
// Update the element - easiet is to use EJS to make sure each house has an id/class with the id in it
// Given an ID of 2 this says find the div with class house_2 and updates its div with class room to the number of rooms
$('.house_' + house.id + ' .rooms').text(data.rooms);
});
}
}
This is more of pseudo code then anything but should put you on the right track.
res.render can't rerender view, for refresh page in second time you need use javascript to replace html. This is not good solution
$.get("/",function(html){
document.open();
document.write(html);
document.close();
});
For better you should use another router to render DOM you want to change

Resources