Sails.js index.ejs controller logic - javascript

I'm a little confused on how to add logic to the home page of my Sails.js app. Right now, its just a static page, but I would like to include data on the homepage (index.ejs). I have a MainController and I included a index: function that is pulling in the data. I can't figure out how to configure my route to allow for this.

From What you wrote I am guessing you are using Express js and ejs template.
If you are using the Express render method in your mainController to render your index.ejs you can send the data with response like:
res.render('index', { data: 'my data' }, function(err, html){
// handle callback and error
});
so here you have sent some data
then in your index.ejs file you can get data using ejs tags like:
<div><%= data %></div>
Tell me more about your mainController method if this is not useful

The static-folder is for static-content only (as the name is telling us). If you want your website to show content dynamically you need to create a controller like that:
module.exports = {
index: function(req, res){
res.view(); // sending the view in /views/{controller_name}/index.ejs
return;
}
}
Cheers!

Related

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

How should I display data from backend in Node.js + jade + angularJS + mongoose

I'm going to make web application (SPA) with:
Backend: Node.js (express)
Frontend: Jade + AngularJS
Database: Mongoose
I will send data (as a form) to backend in this way ExpressJS AngularJS POST (Check ANSWER)
It will be simple CRUD.
However i wondering how should I display data from backend?
For example:
I'll run application
var Partner = require('../model/partners');
router.get('/', function (req, res) {
Partner.find({}, function (err, partnerList) {
if (err) throw err;
res.render('campaign', {
partnerList: partnerList
});
});
});
And how should i display data (partnerList). Maybe in this way?
- each item in partnerList
= item.name
Or maybe there is another better way with angular to display data at view? I'm asking because later i'd like remove or update items from partnerList (CRUD operation). And it may be a problem because i will have to send item._id as a parameter to angular function?
For example if i will add button to remove record:
- each item in partnerList
= item.name
button(type='remove' ng-click="sub('#{item._id}')")
script.
app.controller('view1Ctrl', function($scope, $http) {
$scope.sub = function(id) {
$http.post('/',id).
success(function(data) {
console.log("posted successfully");
}).error(function(data) {
console.error("error in posting");
})
}
});
Probably it won't work correct
As said in previous coment, from my point of view I prefere to send the minimum required data from the backend to the client, but it depends of you infrastructure and you concurrent users.
Example 1:
You have a web app with +5K concurrent users, in this case is better handle all the huge stuff at frondend side or you will need to spend a lot of money in your backend hardware.
Practical case:
Users POST a new comment in a blog page. You sanitize the text string at the backend and put it at you preferred datastore... But JUST respond with a simple json like {"status": "ok"}. If the frond end recive this, modify the DOM with the text string that the client sent to the backend in the POST stage, but not send again all the HTML with this (for example) 500 characters comment.
If server responds with {"status":"error"}, modify the DOM to let the user know what's the problem about his comment (more specified json message {"status":"error", "data":"you comment is bigger than 500 chars"})
Problems:
You need extra frontend code to handle these situations in the client side. So this "maybe" will inpact on the user the 1st time that it visits your page.
Pros:
Less hardware costs
Overall less server response times.
More user interactive website modeling only certain parts of the DOM at any moment.
...
Example 2:
You have a simple page with low concurrent users. Then you choose. Let you backend to handle everything? Or keep working with json responses?
I always use the 1st example. Hope this helps in your question.
I think the preferred method would be to set up a second route from express to specifically render JSON, then use angular's $http method to get that data and use it in your controller. If you want to do it with a single route, you can pass the JSON data as a string to your view on the server-side, but it might get a little unruly.
// app.js
...
partnerList: JSON.stringify(partnerList);
...
// index.jade
div(ng-repeat="item in partnerList")
p {{ item.name }}
button(type='remove', ng-click="sub(item._id)")
...
script.
app.controller('view1Ctrl', function($scope, $http) {
$scope.partnerList = JSON.parse(#{partnerList});
...
EDIT To use the JSON string example, you would have to render using the Unbuffered Code syntax. But I'm not sure how you would do that inside a script. block. To instead go the route of serving JSON separately, change your server routes to this:
var Partner = require('../model/partners');
router.get('/', function (req, res) {
res.render('campaign');
});
router.get("/partner-list", function(req, res) {
Partner.find({}, function (err, partnerList) {
if (err) throw err;
res.json({ partnerList: partnerList });
});
});
Then your angular code will query that /partner-list path with $http.get().
script.
app.controller('view1Ctrl', function($scope, $http) {
$http.get("/partner-list").then(function(result) {
$scope.partnerList = result.data.partnerList;
});
...
});

How to pass request parameters back to Angular

I currently have an app which uses Express with Jade templates.
I'm building a new version of the app using Angular with client-side HTML.
I need access to certain request parameters in order to determine user permissions in my Angular code. My problem is that I don't know how to get ahold of these parameters in my Angular controllers/services.
Below is what currently occurs in Express with the Jade structure:
routes.js:
router.get('/player/:id',
playerRoute.show
);
player.js:
var show = function(req, res) {
res.render('player', {user: req.user});
};
...and now my new version's handler:
var player = function(req, res) {
//res.sendFile(path.join(__dirname, '../v2', 'index.html'));
res.json({user: req.user});
};
The correct user JSON is sent back to my client-side with the code above. When res.json is commented out and res.sendFile uncommented the correct HTML is rendered. My dilemma is how to both render this HTML AND provide my client-side Angular code with the user JSON object?
After all that, your question just boils down to:
MY dilemma is how to both render this HTML AND provide my client-side Angular code with the user JSON object?
You don't. The usual case is to just render the HTML along with the assets needed to render the initial app (hide everything, show a splash screen whatever). Further data (like getting your user) is handled by API calls to your server via Angular's HTTP facilities. That means they are separate. After that API call, your app determines what to render.
Otherwise, you could just render the data in the HTML as some global variable and have Angular pick it up from there. This is messy IMO, but doesn't require a separate API call to get the data.
copied from my own answer to a similar question
To get a variable from server to client javascript try templating a json string into the html and loading it from the javascript. EJS handles quote escaping and I think Jade does too. For reference content!= safeString tells Jade to skip escaping, so does content !{safeString}.
- var user={id:1, displayName:'foo'}
#example
meta(data-userJSON=JSON.stringify(user))
script(src="//code.jquery.com/jquery-1.11.3.min.js")
script.
var user = JSON.parse(
$('#example meta').attr('data-userJSON')
)
console.log(user);
span #{user.id}
span #{user.displayName}
Here's how I ended up handling this situation. I simply created a new API endpoint which I can easily hit with an Angular service. Here's the Node setup:
routes.js:
router.get('/currentUser',
apiController.currentUser.index
);
currentUser.js:
var index = function(req, res) {
res.json({user: req.user});
};
module.exports = {
index: index
};
Still seems odd to me to make an API call to get the request parameters, but it works. Feedback appreciated.

Passing data to view in ExpressJS + Reactjs

I have an app and part of it is to login with twitter.
After successfully logged in, I will usually pass the user data to the template by
app.get('/', function(req, res, next) {
log("The Home page has the user info: ", req.session.user);
res.render('pages/home', {
app: 'home',
user: req.session.user || ''
});
});
And then you can render the template based on the user data.
But in React, how should I pass such data to the component after logged in?
I am thinking of putting the data in the browser directly, but I am not confident about that.
<script type="javascript">
var user = #{user}
</script>
How do you think?? Thanks.
Usually you send the props you pass to the top level component to the client in a script tag.
So, you're doing <MyApp user={user} /> or MyApp({user: user}), you would create a script tag like this:
var code = "<script>var __react_preload_data = "
+ JSON.stringify({user: user})
+ ";</script>";
And on the client side:
React.renderComponent(MyApp(__react_preload_data), document.body);
There is a library that works well with express (and any other view rendering node framework) called react-helper (https://github.com/tswayne/react-helper). It pretty much handles everything you need to do to render react components in your view and pass data to them from the server in any node framework. You just make an entry point (js file) for webpack (the lib has a cli that can generate your webpack config for you) and add a line to your controller and view and your component will render on that page. Passing data into your react components is really simple:
const component = reactHelper.renderComponent('MyComponent', {user:
req.session.user || ''})
res.render('view-to-render', {component})
There is also express middleware for react-helper (https://github.com/tswayne/express-react-helper) that allows you to add context that is available to all views, which is convenient for user session data.
app.use(function(req, res, next) {
req.reactHelperContext.user = req.session.user || '';
});
Then, all of your react components will have the user prop without having to manually add that logic to every controller action.

Angular ngInit formatting

I'm building a MEAN app and I'm trying to pass in data from the server-side into the angular application and I've read that this is possible with the use of ngInit but I'm having a lot of trouble with getting it to work.
My Express route is set up as follows:
app.get('/dashboard', Auth.ensureAuthenticated, function (req, res) {
res.sendfile('./app/views/admin.html', req);
console.log(req.user);
});
The console log message is there for production reasons so I can see the current authenticated user in the terminal.
Now when I try to pass req into ngInit and I'm getting tonnes of errors. If my body is set up like:
<body class="dashboard" ng-controller="DashboardController as dashboard" ng-init="active_user = {req.user}"> ... </body>
This causes angular to spit out:
It looks like you're sending a plain html file with res.sendfile(…) and expecting Express to interpolate a variable.
In order to do what you're asking you'll need to do some server-side templating. It looks like res.render('admin', {user: req.user}); will do the trick, assuming you've modified your admin view to be a proper template.

Categories

Resources