How to use `GET` and `POST` parameters inside Static Assets in ExpressJS - javascript

When using PHP to render pages that make use of the request parameters of GET and POST, we can do something similar to:
<p>Hello, <?php echo $_GET["name"]; ?>!</p>
And when we request the file like: /?name=Mike, we get the following output:
<p>Hello, Mike!</p>
Using Node JS and Express JS, I serve static files using the following universal code:
app.get('/user/:name', function(req, res) {
res.render('user.html', {
UserName: req.params.name
});
});
Here, in the user.html, I would like to use something like:
<p>Hello, <? document.write(UserName); ?>!</p>
<p>Hello, <? document.write(req.params.name); ?>!</p>
Something, that switches into the server side and then gets the params and displays here. Is there any way to do it using the static files, where user.html is a static file?

Yo can do it by using RegularExperssion in Query String
the request URL would be like this "http://servername/Profile?Name=Amir"
app.get(new RegExp("Profile(\\.(?:htm|html))?(\\?.*)?$"), function (req, res) {
var queryData = url.parse(req.url, true).query;
var Name = queryData.Name;
console.log(Name)
res.render(__dirname + "/Pages/AppView.ejs", {
username: Name ,
})
})
in ejs template would be like :
<h1> Welcome , <%= username %> </h1>

Related

Unable to open sqlite DB file from js axios.get request

Unable to open sqlite DB file from js axios.get request:(console.log outputs exception message). The request may call my PHP controller to select data from DB and return it json-encoded.
An another side, PHP contoller makes it's job good: screenshot
In this way i trying send an axios request from Vue form: screenshot
or code:
Vue.createApp({
data: () => ({
processors:'',
memory:'',
drives:'',
motherboards:'',
cases:'',
}),
methods:{
fetchProcessors:function (){
axios.get('/src/controllers/getProcessors.php').then(
(response) => {
this.processors = response.data;
console.log(response);
});
}
},
created:function (){
console.log('vue is ok');
this.fetchProcessors();
}
}).mount(".js-form");
PHP controller code:
<?php
require_once __DIR__ . '/../../vendor/autoload.php';
use Doctrine\DBAL;
$connectionParams = [
'url' => 'sqlite3:///db/calc_db.sqlite3'
];
try {
$conn = DBAL\DriverManager::getConnection($connectionParams);
$data = $conn->fetchAllAssociative('SELECT name, cost FROM processors');
echo json_encode($data, JSON_THROW_ON_ERROR);
} catch (Exception $e) {
echo $e->getMessage();
}
I've tryed to:
give chmod 777 to whole project
make request with phpstorm tools (returns same exception message)
send const json from controller - it wotks good, proofs that js request and php controller working together normaly, trouble is in connection to DB file (i think so)
use sqlite driver instead of sqlite3
full stack trace
The problem was in 'path' param: i've launched my script from project root (working directory), so relative path to my DB builds correctly.
On web-server WD was a path, that i gave in request (controllers dir), so relative path to my DB builds incorrectly.
I've replaced path param like this and everything is OK:
$connectionParams = [
'path' => dirname(__DIR__, 2) . '/db/calc_db.sqlite3',
'driver' => 'pdo_sqlite'
];

How to read JSON file and add the values to HTML page

EDIT:
I just need a simple way to read the json file in the html page, can it be possible without making this complicated? I should be able to have key reference anywhere in the html page without any limitations.
END
I have html page that hosted on the heroku app and I'm trying to read the json file and display the values of json file to the html page, how would I do that?
Here is what I have tried so far.
My student JSON file:
{
name: 'John Doe',
car: 'BMW X5'
}
My HTML page:
<html>
<header>
const fs = require('fs');
let rawdata = fs.readFileSync('student.json');
let student = JSON.parse(rawdata);
console.log(student);
console.log('my Name: ' + student.name);
console.log('my Name: ' + student.car);
</header>
<body>
<h1>My Name is: <%=name%> </h1>
<p>My Car is: <%=car%></p>
</body>
</html>
There are various ways to load a local JSON file into your web page, but only a few preferred ways to present your loaded data.
Fetching local JSON
Load local JSON file into variable
How to read an external local JSON file in JavaScript?
Once you load your data, it is wise to either utilize data-binding or templates to present your data.
Data-binding with knockout
// Data from load
var student = {
name: 'John Doe',
car: 'BMW X5'
};
var StudentViewModel = function(studentData) {
this.name = ko.observable(studentData.name);
this.car = ko.observable(studentData.car);
}
ko.applyBindings(new StudentViewModel(student));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<h1>My Name is: <span data-bind="text: name"></span></h1>
<p>My Car is: <span data-bind="text: car"></span></p>
Templates
// Data from load
var student = {
name: 'John Doe',
car: 'BMW X5'
};
window.addEventListener('DOMContentLoaded', (event) => {
let templateHtml = document.getElementById('student-template').innerHTML;
let StudentTemplate = Handlebars.compile(templateHtml);
document.body.insertAdjacentHTML('beforeend', StudentTemplate(student));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.4.2/handlebars.min.js"></script>
<script id="student-template" type="text/x-handlebars-template">
<h1>My Name is: {{name}}</span></h1>
<p>My Car is: {{car}}</span></p>
</script>
There are 2 approaches to displaying data from a server to the client:
1) You can change your client JS code to make an http request to fetch the JSON and then dynamically update the HTML. Pro: simple, Con: additional http request.
2) Or you can edit the HTML on the server. Pro: avoids http request, Con: slightly more complex.
Server Node code:
const http = require('http');
const myJson = require('student.json', 'utf-8');
let myHtml = require('fs').readFileSync('index.html', 'utf-8');
myHtml = myHtml.replace(/<%=(\w*)%>/, (_, key) => myJson[key]);
http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(myHtml);
}).listen(8080);

express-handlebars # if statement

I am still pretty new to NodeJS and I am using the express and express-handlebar packages.
However, the 'if-statement' does not work properly, in fact not at all. I suppose the reason for this is that I do not use a template for the if-statement.
Using just the package 'handlebars', I would go with:
rs.readFile('files/test.hbs', 'utf-8', function(err, data)
{
var template = hbs.compile(data);
var result = template ({name: 'name', value1: 'value1', value2: 'value2'});
res.end (result);
...
}
This solution works actually.
However, I have already used express-handlebars in the entire code and would like to keep on using it. I got following code:
//I´ll receive value1 and value2 later either directly from my database or with the help of MQTT
var value1 = ' value1';
var value2 = 'value2';
var name = 'name';
var helpers={
value1:function(){return value1;},
value2:function(){return value2;},
name: function(){return name;}
}
router.get('/', function(req, res){
res.render('index', {helpers});
});
My html code looks like following:
<div>
<h1> {{value1}} </h1>
<h2> {{value2}} </h2>
{{#if name}}
<h3> hello there! </h3>
{{/if}}
</div>
value1 and value 2 are shown properly. 'hello there!' isn´t as I suppose it is not a template.
Does anyone know how I can make code work with express-handlebars?
I just answered it by myself.
The solution is:
router.get('/', function(req, res){
res.render('index', {
name,
helpers});
});
add this in server.js
const isEqual = function(a, b, opts) {
if (a == b) {
return opts.fn(this)
} else {
return opts.inverse(this)
}
}
var hbs = require('hbs');
hbs.registerHelper('if_eq', isEqual);

Mongoose $push from HTML Form not working

Can anyone tell me what am I doing wrong.
My HTML Form:
<form action="/user/:id" method="put">
<div class="form-group">
<label>Miles</label>
<input type="text" class="form-control" name="miles">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
My Express Route:
app.put('/user/:id', function(req, res) {
User.findById(req.body.params.id, function(err, user) {
if (err)
res.send(err);
console.log(user.id);
User.findByIdAndUpdate(
user.id,
{$push: {"milesLog": {miles: req.body.miles}}},
{safe: true, upsert: true},
function(err, model) {
console.log(err);
},
res.json(user)
);
Posting from my HTML form I get the following Error:
Cannot GET /user?miles=66&activity=asdasd
But When I test this through POSTMAN it works:
What am I doing wrong. Why doesn't it work from my HTML Form?
The route doesn't match, you have this URL
/user?miles=66&activity=asdasd
and then this route
app.put('/user/:id', ....
that route is looking for something like this
/user/66
it doesn't look for querystrings, that would be
app.put('/user', function(req, res) {
var miles = req.query.miles;
var activity = req.query.activity;
and unless you have a really good reason for using PUT request, you should change that to use GET instead.
Also, <form action="/user/:id" ... isn't a valid URL, you can't have colons in the URL, and you seem to have misunderstood a little, the :id in your route matches anything, as long as it's a valid route, so it will match
/user/frank
/user/77
/user/something?querystring
etc. and then you can access that inside the route
app.get('/user/:id', function(req, res) {
var user = req.params.id; // returns "frank" etc
There is no "PUT" verb in html forms, while you are implementing it like this:
<form action="/user/:id" method="put">
You have to use method="POST" in html form and change your route to:
app.post('/user/:id')
It's not a bad thing to use such method.
However if you are developing a front-end application it's common to use XMLHttpRequest object which has "PUT" verb, and your route will work just fine.

SailsJS - Create versioned API without blueprint

I'm trying to figure out how to create a versionned API for my application.
According to this issue https://github.com/balderdashy/sails/issues/322 , I have to use blueprint, but all blueprint is deactivated in my project (a wish from my boss).
I want to be able to have any URL like http://myapi.com/v1/my-custom-route , and so on for any version.
So far, the best way I've found is to duplicate all controller to something like v322AuthController.js and to map all routes like
'POST /v3.2.2/se-connecter' : 'v322AuthController.perform_signin'
But I think that's an ugly trick. I'm currently using Nginx and all my code is versionned with git
Thank you if you have any idea
Kai23
you have to disable all blueprints? Than you have to write all your routes an our own.
If you don't want to duplicate your controllers you can try this:
config/routes.js
module.exports.routes = {
'post /:apiversion/se-connecter' : {
controller: 'AuthController',
action: 'perform_signin',
skipAssets: true
}
....
}
So Sails passes all */se-connecter to the method "perform_signin" at your "AuthController". In your controller you have your api-version:
AuthController.js
module.exports = {
perform_signin: function (req, res) {
var apiversion = req.param('apiversion');
if (apiversion === "0.2.0") {
....
}
}
}
My approach:
Create subfolder for your controllers as:
/controllers/v1/UserController.js
/controllers/v2/UserController.js
In your routes.js file, add as follow:
'POST /api/v2/user': 'v2/UserController.create',
'POST /api/v1/user': 'v2/UserController.create',
And in your policies.js, you can add middlewares like this:
'v2/UserController': {
'create': ['isAuthenticated','isAuthorized']
}
My current sails' version is: 0.12.3

Categories

Resources