Are you able to use vue.js inside an ejs file? - node.js

Sorry guys I am new to node.js and was wondering whether we are allowed to use vue.js within an ejs file.

Yes, we can. Here is a scenario. Let's say you want to render a data Object to ejs file, and you want this data Object be accessible from VueJS.
First, in your controller, you have to render it as a JSON string
res.render("index", { data: JSON.stringify(data) }); in order to access it in your javascript code.
Then, in your VueJS code inside ejs file, you simply access it this way:
var app = new Vue({
el: '#app',
data: {
myData: JSON.parse('<%- data %>')
}
})
Note about <%- tag in your VueJS code, it is necessary in order to output your data properly.

As VueJS can be implemented into existing systems, you should be able to do so yes.

Related

Controller reference is not defined node.js application

I'm working on a node.js single-page web application where I wanna use MVC. On my back-end, i'm using postgres database to store data that will be provided by the user throught forms interaction. For this, i'm also using Sequelize.
When 'npm start' runs, the application verifies if the database already exists locally, if not, then it is created with its tables and relations, just as expected.
On my front-end, the application loads a file called index.html (where all forms will be located). In this file, I'm trying to use my controllers to call 'create' methods using Sequelize, but i can't exacly call those functions on html script tag.
The first errors i was getting was 'required is not defined' when I was trying to do things like 'var PropController = require('../controllers/PropriedadeController.js')'. After some research, just figured out that it has somethings to do with browser/client-side in JavaScript.
I'm now trying to deal with this using Browserify, but still can't find out how it fits in my case. I did some research, but couldn't find a similar situation.
Basically, my idea is to reference all my controllers in a script.js file, and then browserify this file, in order to use it in my html file in the script tag.
My controller file:
const models = require("../models")
exports.findCreate = obj => {
return new Promise((resolve, reject) => {
models.Produtores.findOrCreate({
attributes: ["propt_nomeProdutor"],
where: { propt_nomeProdutor: obj.propt_nomeProdutor },
defaults: {
propt_nomeProdutor: obj.propt_nomeProdutor
}
})
.then(resp => {
resolve(resp);
})
.catch(e => {
reject(e);
});
});
};
My script.js file:
const ProdController = require("./ProdutorController");
module.exports = ProdController
And in my index.html file, after running 'browserify script.js -o bundle.js', i'm calling this generated script. So now, Inside a script tag, i'm trying to:
`(html form here)
<script src="../controllers/bundle.js"></script>
</body>
</html>
<script>
// ProdController.findCreate(obj) ...
</script>`
After trying this, i'm getting an error 'ProdController is not defined'. I even tried to browserify my controller file and my script.js into the bundle.js file, but then i'm getting an error witch I couldn't solve either:
Uncaught Error: Cannot find module './dialects/postgres/data-types'
I would like to know if there is any solution for this. I'm afraid that it's not possible to do this using these dependencies all together. I did a similar application using Electron, but now i'm trying to deal with a browser, and can't figure out how to do it.
This project is in my github repo: https://github.com/gabrielftwgarcia/TCC2
Any help will be greatly appreciated.
I think you are not familiar with front-end and back-end concepts. Controller is used at back-end side and it cannot use at front-end side. If you want to call a controller method you should write a new router to execute that method.
And another important thing is require method belongs to Node scripts and cannot be used at front-side.

MongoDB, Node, Express, EJS - Pass a array/variable from backend to frontend (from route to client)

I've been trying to figure out a better way to push a variable from the backend to the frontend. Right now I do something like this.
I have a MVC-pattern, so when hitting the route
app.get('/fil', middleWare.isLoggedIn, user.fil)
... trough node does some querying the DB, and pass on the data.
exports.fil = async (req, res) => {
try {
faktura = await Lan.find().populate('client', 'namn kundnr')
res.status(200).render('pages/createInvoice', {
faktura: faktura
});
} catch (err) {
return res.status(500).send({
message: err.message || "Some error occurred while retrieving datas."
});
};
};
... it generates the page, with the help of EJS (i love EJS) and then pass it on to the client/user.
And in the .ejs-file that is served to the client/user I add the following
<script>
var fakturor = <%- JSON.stringify(faktura) %>;
</script>
which then means that I use up the variable and work with it with JS.
And this is where my question pops up. Is this a good way to do it or is there any other way to handle it?
I guess one idea is to let the user to query the DB straight from the page, but in my case I believe it wouldn't actually be better for the user to do so (the user will reieve like 100 different rows that they will be able to filter and then download a file of)
But is there any other ways I could do this without the script-tag? Like i said, I guess a ajax-call from JS/the client could be used but could you do it any other way? Can EJS do it any other way?
ejs is used for static pages mainly, if you want to build a dynamic page I would look for a single page application framework like angular and react.
if you still want to use ejs you can use ajax call to the server to load a variable from the DB.
I would never query directly from Front end to DB because then you are not controlling the security of the server, always go through the BE.
also try to think if you really need a variable in the front end, can you solve your problem using rendering only?

How to send server-side variables to vue instance using webpack & vue-cli?

I am currently making a project using vue-cli which generates a Node project with webpack. I can build all scripts and use the pug language within .vue files. When building, the project uses HTML-Webpack-Plugin, though, which outputs the code as static HTML with client-side scripts.
How do I pass variables from the server-side to these client-side scripts? I previously was using pug, which made this process easy, but since it now gets built into .html files, this can no longer be done.
I have two attempts, both suboptimal:
1. Send variables into clientside scripts
script.
const clinetSideVar = `!{serverSideVar}`;
The problem with this approach is that I cannot pass this variable into the vue instance, since it gets obfuscated when built and I have no way of accessing it (or do I? I haven't found a way).
2. Using AJAX requests
I could also make a restful API for server-side site data and retrieve it using AJAX, but this seems like a real hack and this would lose quite a bit of performance over just sending the data plainly through a pug template (with no. 1 I'd too, since client-side JS would have to insert the data into the DOM).
I'd recommend using JSONP (since your index.html is built ahead of time in Vue-cli).
In your public/index.html (which is a template)
<head>
...
<script>function getServerData(data) { window.__SERVER_DATA__ = data; }</script>
<script src="/api/server-data.json?callback=getServerData"></script>
</head>
In your Node Express routes definition
const app = express();
// ...
app.get('/api/server-data.json', (req, res) => {
res.jsonp({
foo: 'foo',
bar: 'bar'
});
});
Then just access window.__SERVER_DATA__ from within any Vue component.

Passing Data from Node-Express backend to Vue component

I'm still learning Vue.js 2 so I do apologize if this question is a bit silly. I'm building an application using MongoDB, Node, Express and Vue. Normally I'd use a template engine such as Ejs where data passed through Express's res.render method can be readily captured in the template.
Is there a similar way to pass data from backend to the root Vue component? For example, normally, a get request fetches some data from Mongodb, express will render the template file and pass data to it.
app.get("/gallery/:id", function(res, req) {
var id = req.params.id;
database.findById(id, function(err, data) {
....
res.render("home", data);
}
});
Now my root Vue application is attached to html file. I'd like to be able to dynamically render the app with data returned from the database.
I've built an app before that streams data from an api and passed it to my Vue component via socket but I feel like using a socket in this case is unnecessary.
Use http. What's the problem? You can use XmlHttp, or a lot of folk seem to be using Axios. Trigger the call in the onload of your page, or use one of the vue lifecycle hooks. The very good vue docs don't have much to say about how and when to do this. We do it in the onload of the page, and we instantiate vue when the request for page data returns.
The question has already been answered, but I wanted to share my approach. I've been experimenting with rendering an object server side using res.render(), putting it in a div where display: none, and then grabbing the object on the client and passing it to Vue's data attribute.

node.js how to access its html file

I'm working on an app that uses a node package for some of its content and css. How do I access the templates? The folder structure for the package is packageName/src/packageName/templates/basket/partials/index.hbs The contents of that file is only html.
I want to use the contents of index.hbs in one of my app's hbs files. In the route handler for the page I have set up a variable to get that data and pass to the view, but I dont know how to expose the contents of the index.hbs file to the route handler. Do I read it in the fs package? or is there another way to access it?
I'm inexperienced with node so let me know if I need to provide more information.
Using require in the route handler worked nicely.
route_handler.js
const html = require('packageName/src/packageName/templates/basket/partials/index.hbs');
module.exports = {
res.render('pageView', {
html: html
});
};
pageView.hbs
{{{ html }}}

Resources