How to manually navigate to route with React + React-Router-Component - javascript

I've created a React component library, which JS react page views render and control.
// Application js, controls the routes.
var Application = React.createClass({
mixins: [Router],
routes: {
'/': HomePage,
'/users': PerformerPage
// , null: NotFoundPage
},
render: function () {
return this.transferPropsTo(this.renderRouteHandler());
}
});
// and in HomeView.js, a link to a page
<Link href={'/users'}>{'Test'}</Link>
This all works wondefully. Except when i manually navigate to that link, it clearly doesn't handle it yet... so my question is, if the server redirects to the index ALWAYS, will react catch this? I'm pretty well versed in grunt, and build automation in general, but node js servers aren't my forte yet unfortunately.
In my grunt server
task =>
'connect:livereload',
'webpack:development',
'open',
'watch'
Final result: User should paste address into bar (ie site.com/users) and be navigated to the applications /users.
Thanks :D Any help would be great.

One way to do it is to put the routes in their own file (say client/routes.js)
module.exports = {
'/': HomePage,
'/users': PerformerPage
// , null: NotFoundPage
};
Now you can require them in your Application file, and in your node server:
var app = require('express')();
var routes = Object.keys(require('../client/routes'));
routes.forEach(function(route){
app.get(route, function(req, res){
res.sendFile(__dirname + '/static/index.html');
});
});

Related

Express.js returning multiple routes in a single exported router object returns incorrect route

I am trying to utilize an MVC pattern for express. I am modularizing routes and trying to declare the express router in only the server entry file and nowhere else.
My current issue is when exporting my appRoute function in my main routes file (see below), the first route (user route), returns users. I have another route called game that is exported in the same function but it still returns users instead of games.
Both routes have a controller function called getAll that gets different data from different tables.
If I try and visit the route: http://localhost:8000/user/getAll, it returns all users just fine.
If I try and visit the route: http://localhost:8000/game/getAll, it still returns all users even when they're different routes...
If I were to flip the order of users and games in the main routes file where game is first and user is second, users starts to return games. It's like the second route mimics the first route.
This may be something simple, but any help I will appreciate.
My code is as shown below
server entry point (index.js)
const app = express();
const router = express.Router();
const bootstrap = require('./src/bootstrap');
bootstrap(app, router);
I am passing on the app and router instance to my bootstrap file where all routes will be exported to.
bootstrap.js (this file gets all exported routes and uses them within the app)
const { appRoute } = require('./routes');
module.exports = (app, router) => {
return app.use('/', appRoute(router));
};
I am passing on the router instance to my main routes file where all routes are exported from.
Main routes file (index.js): this file requires all routes and uses them within the router instance. I think this might be where my issue is but I am a little stuck on how I might fix it.
const { userRoute } = require('./userRoute');
const { gameRoute } = require('./gameRoute');
exports.appRoute = (router) => {
router.use('/user', userRoute(router));
router.use('/game', gameRoute(router));
return router;
};
Game route files (index.js): returns all users instead of games
const { gameController } = require('../../controllers');
exports.gameRoute = (router) => {
return router.get('/getAll', gameController.getAll);
};
Any help is greatly appreciated. If there is any clarification needed please let me know.
I think you need to create a separate router for game and user.
See the express.Routing section and birds.js example here

Redirect page on vue.js from node.js

So, I have my Vue.js app running on localhost:8080 and my Node.js server running on localhost:3000. I am implementing a reset password code, where I generate a token, and then send an email to the registered emailid. The email consists of a link that looks like :
localhost:3000/auth/resetpassword/40700dc92bb7be1ccf65fb120294f30a3be0e5b9
Now by clicking on this link, I should be able to route that to a vue-router, but I do not know how that is to be done.
I also noticed that I will need a link that starts from localhost:8080 to even access my vue.js app. So is there any way you can make the server render a vue.js page?
Thank you.
create a route /auth/resetpassword/:id
const NotFound = { template: '<p>Page not found</p>' }
const Home = { template: '<p>home page</p>' }
const Resetpassword = { template: '<p>Reset password</p>' }
const routes = {
'/': Home,
'/about': About,
'/auth/resetpassword/:id' : Resetpassword
}
new Vue({
el: '#app',
data: {
currentRoute: window.location.pathname
},
computed: {
ViewComponent () {
return routes[this.currentRoute] || NotFound
}
},
render (h) { return h(this.ViewComponent) }
})
which can be accessed by $route.params.id
There are tons of ways to make the server render a vue.js page. It depend on what you need on real production app.
Method 1: Serve your Vue app as static resources
You can just adjust your webpack bundle output path to your Node.js public directory. Serve them as static files(html document, css, js ...) in your Node.js server, just like any multi-page application you have. So you have to define every route rules the Vue app has to your node.js routes including /auth/resetpassword/. Also review all your static resource path. And you can access the vue app by localhost:3000/auth/resetpassword/.
If you use Vue CLI 3 and express:
vue.config.js
// adjust bundle output path:
module.exports = {
// ...
outputDir: '../your-node-server/public/vue-app/',
assetsDir: '../your-node-server/assets/',
// ...
}
// and run `vue-cli-service build`
/your-node-server/routes.js
app.get('/auth/resetpassword/:token', function (req, res) {
res.render('./public/vue-app/index.html');
});
// vue app may access some static assets e.g. http://localhost:3000/assets/logo.png
app.use('/assets', express.static(__dirname + '/assets'));
Method 2: Separate Vue app server and API server
You can serve the vue app on the same way. Make the request url which has /api prefix to access localhost:3000, others request to access localhost:8080 by adjusting your nginx config providing reverse proxy.
something like:
etc/nginx/conf.d
// ...
location /api {
proxy_pass http://127.0.0.1:3000;
// ...
}

React and Dynamic Routes including Filename and Extension

I am new to React and trying to put a CMS driven application together as kind of a POC. I am majorly stuck on how to get a full URL (including filename and ext) into a dynamic route in a React application. For example if I call this
http://localhost:8080/en/us/fly/index
The dynamic route picks it up. But if I call this
http://localhost:8080/en/us/fly/index.html
I get the following error. Cannot GET /en/us/fly/index.html
It is a requirement that I handle all URLs through my route even if they have a file extension & filename. My routes.jsx is as follows:
import React from 'react';
import {
Switch, Route
} from 'react-router-dom';
// Pages
import Page from "./pages/Page";
class Routes extends React.Component {
render() {
return (
<Switch>
<Route path="/:page" component={Page} />
</Switch>
)
}
}
export default Routes;
and my server.js is as follows:
const path = require('path')
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;
// get an instance of router
const router = express.Router();
// serve static assets normally
router.use(express.static(__dirname + '/dist'))
router.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, 'dist', 'index.html'))
})
// apply the routes to our application
app.use('/', router);
app.listen(port);
console.log('Site available on port ' + port);
How can I get all URLs to pass through my dynamic route? Is this even possible? I need to know if there are limitations in React that prevent this vs how it would work in a traditional ASP.Net MVC application where I can do this kind of dynamic routing.
Any help or advice on this will be very much appreciated as I am very stuck with this and don't fully understand the React world enough to find the solution.
Thanks in advance,
You can use *.* in your route. It matches with file extensions as below
<Route path="*.*" component={YOUR_COMPONENT}/> // matches /hello.jpg and /hello.html
Then you can access the props in your component as
// CMS name: sample.html
this.props.params.splat[0] // For name of prop without extension. It Will give 'sample'
this.props.params.splat[1] // For extension itself. It will give 'html'

Ember error on refresh or direct URL

I was unable to find any current answers for this question.
I am building my latest project in Ember and while I am able to access the different routes directly and with refreshes locally, as soon as I build for production and host the site, this no longer works. I believe the slug portions of my routers are correct so not sure what I need to update.
Note: I am using Ember CLI.
Router.js
const Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('reviews', function() {
this.route('index', {path: '/'});
this.route('review', {path: '/:review_id'});
});
this.route('movies');
this.route('about');
this.route("error", { path: "*path"});
});
Review Model
export default Ember.Route.extend({
model(params) {
const id = parseInt(params.review_id);
const movies = this.get('movies');
return movies.getMovieById(id);
},
movies: Ember.inject.service()
});
If I try to directly access or refresh /about, /reviews, /movies, or /reviews/:review_id I am given a 404. Even though the about route doesn't have a model to retrieve any data. It's simply loading a template. The only route I can refresh on is the very index page of the site.
I found this link here which instructed how to update your htaccess file to redirect requests to Ember's index file. This looks to have solved my problem:
http://discuss.emberjs.com/t/apache-rewrite-rule-for-html5-browser-history-url-bookmarkability/1013

EmberJS: Change path to access a route

I have a Router.map defined to my application. I'm working with EmberJS AppKit architecture. https://github.com/stefanpenner/ember-app-kit
I'd like to access to my page "profile" using the following path:
http://localhost:8000/#/profile
But, the name of my route differ to this path, because it's call user-profile, so I did this:
router.js
var Router = Ember.Router.extend();
Router.map(function () {
this.resource('user-profile', { path: 'profile'}, function() {
//Some other things...
});
});
export default Router;
user-profile.js
export default Ember.Route.extend({
model: function () {
return this.store.find('user-profile');
}
});
When I launch my application, Ember is telling me that profile route doesn't exist, even though I defined the path:
Uncaught Error: Assertion Failed: Error: Assertion Failed: The URL '/profile' did not match any routes in your application
Do you know what's wrong with my code at this point?
Thanks
I dont use ember appkit but perhaps try with underscore, ie 'user_profile' and rename your file too. Just a shot in the dark.
I would have to guess it is the way that you are designing your router and the namespace.
Typically a barebones Ember app requires:
window.App = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true
});
App.Router.map(function () {
this.resource('user-profile', { path: 'profile'}, function() {
//Some other things...
});
In your example your router is not in the App namespace, or whatever your root object is named (It doesn't have to be 'App'). I would give this a try or maybe post more code if there are other factors I do not see here.
Also, typically you would name your route userProfile. While i dont think the dasherized name is a problem, it doesn't follow Ember naming conventions.
Hope this helps.

Categories

Resources