How should routing html pages be done for website? - express

I'm using MEAN stack. For example, if I click on a item, how does it route it's item page like *****.com/item/[id]? How does it go to that item page for that id? Is this done using node and express?

Call the route and send file, somelike this...
app.get('/item/:id', function (req,res){
console.log(req.params.id); be show the param id
res.sendFile('page.html', {id: req.params.id});
)};
More aboute routes

Okay, you need to understand routing mechanism of single page applications. Now you should be aware that your root path that is '/' will be served by express
app.get('/', function(req, res) {
res.sendFile('index.html', { root: path.join(__dirname, '../public') });
});
As soon as your index.html is served to the client, Angular will take over all the routing. You must use a routing solution for that(ui state or ngRouter). if you want to go to a particular route in angular containing some id you can create a route like this(assuming you are using ui-state router)-
$stateProvider
.state('user', {
url: "/user/:id",
templateUrl: "/angular/users/views/user.html",
controller: "UserCtrl"
});
In your html file you will write -
<a ui-sref="user({id: userId})">
Here userId is the id you want to pass to the route.
Hope it helps!

Related

How to pass through multiple requests on a route EXPRESS JS

I'm trying to pass through a view as well as a json file so that I can manipulate it within the view.`
var express = require('express');
var router = express.Router();
var data = require('../monsters.json');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
res.json(data);
});
module.exports = router;
`
It passes through the render of the index.ejs view but in the console there is no indication of a json file with it. Nor is there any way to manipulate the file and read it. I'm not sure if I'm just being silly and the method for passing it through doesn't exist.
EDIT: I've now tried this and am pretty sure its being passed through, is there anyway I can verify that the file has been passed through? `
router.get('/', function(req, res, next) {
res.render('index');
res.header("Content-Type",'application/json');
res.sendFile(path.join(__dirname, 'monsters.json'));
});
`
You can't send multiple responses. You get one response per request.
If the file you want to include is JSON, then you can embed it into a <script> tag in your HTML page using your template engine so everything would be in your HTML page and it can be the one response. Then, the JSON will get parsed automatically into a Javascript object that is available to your page's Javascript.
The other alternative is that you have the Javascript in the page make it's own Ajax call to your server to fetch the desired JSON in a separate http request. You would then make a route on your web server for handling that Ajax request and sending back the desired file.
As far as I am aware, you can't respond twice - you can however seemingly provide a callback to res.render(view, locals, callback) so perhaps you can serve it then. Otherwise, I would bake it into the view by generating the view on the backend with the file content as a parameter.
For more info, see;
http://expressjs.com/en/api.html#res.render

Vue-Routes redirect doesn't work and beforeEnter render App component again

I'm getting some issues when trying to redirect to an external link.
for ex:
{ path: '*', redirect: 'https://google.com'}
when I use "redirect" it doesn't work completely, but when I use something like that
{ path: '/*',
beforeEnter(to, from, next) {
window.location = "https://google.com"
}
}
it works but there is a problem because first, it tries to render App component again but there is no component so be empty and a blank page is being rendered for nearly 1-1.5 second then it redirects to target URL and I don't want it to reload App component, just redirect it to other link. I googled but found nothing noteworthy.
Or maybe is there another way like deactive a component or use v-if or directly rendering a html file?
redirect is meant to redirect to another route defined by your application, not to go to another website directly.
window.location works, but I think the behavior is somewhat browser-dependent.

How to setup Express for Aurelia Routing?

How do I specify a catchall or actually a catch[most] for express so when the user selects refresh on a page that is actually contained in the app bundle, the GET doesn't fail.
home.html
profile
app.js
config.map([
{ route: ['', 'home'], name: 'home', moduleId: 'home' },
{ route: ['profile'], name: 'profile', moduleId: './profile/profile'}
]);
If I click on the profile link, the URL shows localhost://profile and the page renders correctly without performing a GET because the requested resource was bundled in the initial GET. But lets say I refresh the page with localhost://profile, then it makes a server GET request for that page.
If on the server I specify something like:
app.use('/', express.static(__dirname));
app.use('/profile', express.static(__dirname));
It works properly. I was anticipating some type of catch all formatting so I don't have to add every possible route for an app with all routes bundled. Something like:
app.use('/*', express.static(__dirname));
Then the following to capture GET's for another app
app.use('/othercoolapp/*', express.static(__dirname)+'/othercoolapp/');
But it doesn't work...
This issue you're encountering applies to every single page application framework and library with pushState routing enabled.
Above your app.listen or equivalent line of code in the file that bootstraps your Express server, add something like this:
app.get('*', function(request, response){
response.sendFile(path.join(__dirname + '/index.html'));
});
The general idea is that this generic wildcard route will capture all URL requests and send the index.html file. This allows Aurelia to handle its own routing.

Redirect within MapUnknownRoutes in Aurelia

I want bad routes to navigate to the root route. I've added a mapUnknownRoutes configuration on my router.
config.mapUnknownRoutes((inst) => inst.config.moduleId = 'home');
But this leaves the route untouched. For example, #/fakeRoute routes to home. Ideally, I would like a behavior similar to returning { redirect: '#/' }, which cancels navigation and creates a new navigation to the route '#/'. Is this a feature?
The mapUnknownRoutes method also accepts a RouteConfig object so you can just directly specify your redirect there:
config.mapUnknownRoutes({ redirect: '#/' });
See the complete signature of the method on github

res.render for routes on page reload?

(Using MEAN with UI Router)
The following code sends a json response for the route defined. This works fine when the template is rendered with UI Router; however, if I reload the page, because the response only contains json, I am left with an empty page rendering no html, only the json response.
router.get('/posts/:post', function(req, res, next) {
req.post.populate('comments', function(err, post) {
if (err) { return next(err); }
res.json(post);
});
});
Assuming this is a standard issue, how can I best allow this page to res.render('index') when the page is reloaded and respond with the json response? Should I,
Create a separate route for the json response which is called as a post promise with UI Router
Have the /posts/:post route simply respond with res.render('index')?
Thank you for any responses, not sure what the usual practise is for such issues!
It took me a while to find a working solution to this due to many of the examples online having different directory structures. I placed a catch all at the end of my routes so that url requests to any UI Router states would not be met with a 404, but instead always return the index.html file.
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('index.html', { root: __dirname });
});
Then I added prefixes to my express routes, e.g. /api/posts/:post etc. Apparently express routes should not clash with any of the angular defined routes. Thanks to NormySan on reddit for informing me about this.