Ajax with node.js/jade - javascript

I'm searching for a way to use ajax running on node.js, express and jade as template-engine without routing to subpages. I read this: Node, Express, Ajax, and Jade Example
But this doesn't work for me. I don't want to make a route to a partial part of page, so the user could access the partial page. I just want to serve a convertet jade file in a part of the website.
I think about something like this:
$( ".trigger" ).on( "click", function() {
$( ".result" ).load( "ajax/test.jade" );
});
How could I do this without setting a route in node.js so the user could access the subpage without accessing the whole page.
Thank you for your answers.

What if you send the file as a GET parameter:
var jade = require('jade'),
fs = require('fs');
app.get('/ajax', function(req, res) {
fs.readFile(req.query.file, 'utf8', function (err, data) {
if (err) throw err;
var fn = jade.compile(data);
var html = fn({});
res.send(html);
});
});
and send request like
/ajax?file=test.jade
If you do the things like that you will have only one route.

(Still requires a route but) You could set up a route that only provides a valid response if it is an ajax request, and a 4xx if otherwise
app.get('/path', function(req, res) {
if(req.xhr)
{
...
}
});
req.xhr Express docs.

You could place a jade template (or HTML file) in the public folder on your website, assuming you have it set up.
For example, in the app.js:
app.use(express.static(__dirname + '/public'));
Place the template/file in (or any subfolder):
/public/example.html
Then you can use $.get to load the file, like the link you provided:
$.get('/example.html', function(result) {
$('#test').html(result);
});

I have a problem with ajax call
Server side:
router.get('/user/letterlist', function(req, res) {
// ... some operations
res.render('userLetterList', { title: 'test', rows : rows? rows: null, pageCount: pageCount,itemCount: itemCount });
});
Client side index.jade
extends layout
block content
div(id="userLettersList")
button(type="button" class="btn btn-success")
{success}
script.
$(".btn").click(function(e){
e.preventDefault();
$.ajax({
url: "/user/letterlist",
success: function(data){
$("#userLettersList").html(data) ;
}
});
});
client side userLetterList.jade
table(id="UserLetters" class="table table-striped table-bordered")
thead
....
The problem is when push on the button to load data into the div, it will retrieve and show, but the page redirect to nowhere with a blank page, after some m-seconds.

Related

load a returned HTML file

I have a HTML button, upon clicking, it will send a get request to get a HTML file, and I would like to load the got HTML file to replace the current HTML file I have.
The frontend codes look like this:
document.getElementById("single_user_button").onclick = function() {
$.get('/profile', {token: idToken}, (res) => {
console.log(res);
})
}
And I am using an Express router to handle this:
router.get("/profile", (req, res) => {
res.sendFile(path.join(__dirname, "../public/html/main/ll_profile.html"));
});
I can see the ll_profile.html in the res variable. But I have no idea how to load it up to replace the current HTML page. I tried the JQuery .load(), but that is for loading into an ID. How should I do this?

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

Routing in MEAN Stack - Routing help for Angular js and node.js using expressjs framework

I have solved the problem but I am still unsure if the way I am doing it is correct. If there is any alternative method via which I can send the file and data in one go then that would be more useful. Please give your inputs on the same.
I am using Angular js for the front end and Express js over node.js at the backend.
What I am trying to do?
I am trying to implement something like facebook's facility to provide you unique profile names or say user names.
Therefore - The user let's say types domain.com/hisprofileid
Now, what I want to do is a search should be done on the server side which would send response to front end with exact data depending upon the search's result.
and then front end will load the data.
What I have done till now?
Honestly speaking I haven't been able to think it out properly and the system I have put in place doesn't work.
This is what I have done. The root call that is localhost:portnumber on server side sends a file called index.html. This is just index file and nothing else.
Now on the server side I have made route to handle localhost:portnumber/anything which sends profilepage.html file as response.
Now the controller of that profilepage.html's controller using $locationprovider has this code to make a separate call to server side (Please refer to code below) [I strongly believe this is insignificant and that is why I'm lost]
Please look at some codes given below.
Front end part
$routeProvider
.when('/', {
templateUrl: 'index12.html',
controller: 'someCtrl'
})
.when('/:merchantid', {
templateUrl: 'index12.html',
controller:'userCtrl'
})
app.controller('userCtrl', function ($scope, Upload, $timeout, $http) {
console.log("Here");
var merchantid = "suresh";
$http.get('/merchant/' + merchantid ).success(function(response)
{
console.log("response");
console.log(response);
});
});
Server Side
app.get('/', function (req, res) {
console.log("Global");
res.sendFile(__dirname + '/public/index13.html');
});
app.get('/:merchantid', function (req, res) {
console.log("we are here");
console.log(req.params);
res.sendFile(__dirname + '/public/index12.html');
});
app.get('/merchant/:merchantid', function (req, res) {
console.log("Detail here");
console.log(req.params);
res.json({message: 'here'});
});
Please suggest something.
This is what I have done to solve the problem.
localhost:portnumber/anything - When this is called I am making a call to the server directly and a check is made if that particular person actually has signed up or not and then based on that result the appropriate page is opened.
app.get('/:profileid', route_profileid.fetchprofile);
Then the function to handle the data associated with it.
modename.findOne({
'profileid': uniqueid
}, function (err, docs) {
if (err) {
console.log("Error in finding data" + err);
} else {
if (docs) {
console.log(process.cwd());
res.sendFile(process.cwd() + '/public/profile.html');
}
if (!docs) {
console.log("Nothing Found related to that query");
res.sendFile(process.cwd() + '/public/error.html');
}
}
Now the profile page is loaded with profile data of that specific used and then here is the code of angular's router. [This angular code is attached to the profile page which will be shown.]
$rootScope.$on('$routeChangeSuccess', function () {
console.log($routeParams.profileid);
var profileid = $routeParams.profileid;
$http.get('/profile/' + profileid).success(function (response) {
console.log(response);
$scope.profile = response;
});
});
Note: Inclusion of $RouteParams, $route, $routeScope and ngRoute module to facilitate the activity is required.
Here a new request is made for the actual data of that user.
app.get('/profileid/:profileid', route_profiledata.profiledata);
and then in that specific function data is fetched from the db and appropriate response is sent back to the user.

Stormpath Custom Data

I requested stormpath user custom data by using
res.render('home', {
title: 'home',
user: req.user.customData,
});
i expected to receive a json object of custom data but instead a url ('https://api.stormpath.com/v1/accounts/WvtGbIH3kJ4rEttVF5r9U/customData') was returned. This page does have the custom data i want on it but i cannot request it using an ajax request as it is a https page. What should I do? Thanks in advance
You'll need to use the "auto expansion" feature of the library, like this:
app.use(stormpath.init(app, {
expandCustomData: true,
});
That will expand the custom data resource for you. By default it's just a link to the resource, as you've seen.
Found the best way to request custom data is to use the getCustomData() method in the route, set the data to a variable and use a get request from the client to request this data as in the sample below:
Server Js
customData = new Array;
router.get("/string", function(req, res) {
req.user.getCustomData(function(err, data) {
customData = data.someKey;
})
res.send(customData) /*Returns Empty Arrray*/
})
router.get("/cdata", function(req, res) {
res.send(customData) /*Sends Actual Custom Data*/
})
Client Js
var customData = new array
$(document).ready(function() {
$.get("/string", function(string) {
/*Tells server to get customData*/
})
$(document).click(function(){
if(pleaseCount===0){
$.get("/cdata", function(data) {
for(i=0;i<data.length;i++){
customData.unshift(data[i])
pleaseCount=pleaseCount+1
/*Custom data is now stored in client side array*/
}
})
}
})
That's what worked for me anyway. I don't know why someone down-voted the question as this is an acceptable way to retrieve other user information such as name and email by using userName:req.user.userName in the render function and rendering this information to a p. tag in a jade page by using p #{userName}

How to create a ajax POST with node JS?

I am not sure how to use an ajax POST to POST from a Jade Page to Node JS. If someone can provide an example or tell me what I am missing from the script I have, please let me know.
This is the script file:
//Add friends
$('.addContact').click(function() {
$.post('/addContact',
{friendRequest: $(this).data('user')});
if($(this).html!=='Contact Requested') {
return $(this).html('Contact Requested');
}
});
The url I have for a POST on my app.js file is:
app.post('/addContact', user.addContactPost);
I am trying to post true for a click event on the button Add Contact and change it to Contact Requested if the data in the db is shown as true.
This is the jade file:
extends layout
block content
div
legend Search Results
div#userResults
for user in ufirstName
a(href='/user/#{user.id}')
p #{user.firstName} #{user.lastName}
button.addContact Add Contact
The route file is this:
exports.addContactPost = function(req, res, err) {
User.findByIdAndUpdate(req.signedCookies.userid, {
$push: {friendRequest: req.body.friendRequest}
}, function(err) {
if(err) {
console.log("post2");
return console.log('error');
//return res.render('addContactError', {title: 'Weblio'});
}
else {
console.log('postsuccess');
//alert('Contact added');
res.json({response: true});
}
});
};
If you are posting AJAX request, then you are expecting from JS on client-side to get some response, and react to this response accordingly.
If it would be separate request to another page - then probably rendering whole page - would be actual option.
But as you just need to get response from server and then update your front-end without reloading based on response, then you need to response from server on this POST request with some JSON. And then on client-side, do some templating, use jQuery or some templating libraries on client side for it.
Everything looks good I just think the $.post code is a little off. This might fix your problem.
$('.addContact').click(function() {
$.post('/addContact', { addContact : true }, function(data){
console.log('posting...');
$('.addContact').html(data);
});
...
});
The object I added to the $.post is what is going to be sent to the server. The function you specified at the end is your callback. It's going to be called when the function returns. I think that may have been some of your confusion.
Your node route should look something like this
exports.addContactPost = function(req, res, err) {
User.findByIdAndUpdate(req.signedCookies.userid,{
addContact: req.body.addContact
}, function(err) {
if(err) {
console.log("post2");
res.render('addContactError', {title: 'Weblio'});
}
//assuming express return a json object to update your button
res.json({ response : true });
});
};

Categories

Resources