| 
									
										
										
										
											2015-07-03 17:40:12 -07:00
										 |  |  | import React from 'react'; | 
					
						
							| 
									
										
										
										
											2016-03-02 19:45:54 -08:00
										 |  |  | import { RouterContext } from 'react-router'; | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  | import debug from 'debug'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import renderToString from '../../common/app/utils/render-to-string'; | 
					
						
							|  |  |  | import provideStore from '../../common/app/provide-store'; | 
					
						
							| 
									
										
										
										
											2015-12-22 19:28:07 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 09:33:55 -08:00
										 |  |  | import app$ from '../../common/app'; | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  | const log = debug('fcc:react-server'); | 
					
						
							| 
									
										
										
										
											2015-07-01 15:14:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // add routes here as they slowly get reactified
 | 
					
						
							|  |  |  | // remove their individual controllers
 | 
					
						
							| 
									
										
										
										
											2015-06-29 12:01:56 -07:00
										 |  |  | const routes = [ | 
					
						
							| 
									
										
										
										
											2016-02-02 21:00:48 +11:00
										 |  |  |   '/videos', | 
					
						
							|  |  |  |   '/videos/*' | 
					
						
							| 
									
										
										
										
											2015-10-19 23:16:56 -07:00
										 |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-22 19:28:07 -08:00
										 |  |  | const devRoutes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-29 12:01:56 -07:00
										 |  |  | export default function reactSubRouter(app) { | 
					
						
							| 
									
										
										
										
											2015-07-02 23:44:34 -07:00
										 |  |  |   var router = app.loopback.Router(); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-29 17:55:42 -07:00
										 |  |  |   // These routes are in production
 | 
					
						
							|  |  |  |   routes.forEach((route) => { | 
					
						
							|  |  |  |     router.get(route, serveReactApp); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-10-19 23:16:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 11:09:34 -07:00
										 |  |  |   if (process.env.NODE_ENV === 'development') { | 
					
						
							| 
									
										
										
										
											2015-10-19 23:16:56 -07:00
										 |  |  |     devRoutes.forEach(function(route) { | 
					
						
							| 
									
										
										
										
											2015-08-13 11:09:34 -07:00
										 |  |  |       router.get(route, serveReactApp); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   app.use(router); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function serveReactApp(req, res, next) { | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |     const serviceOptions = { req }; | 
					
						
							|  |  |  |     app$({ | 
					
						
							| 
									
										
										
										
											2016-03-02 19:45:54 -08:00
										 |  |  |       location: req.path, | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |       serviceOptions | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       // if react-router does not find a route send down the chain
 | 
					
						
							| 
									
										
										
										
											2016-03-02 19:45:54 -08:00
										 |  |  |       .filter(({ redirect, props }) => { | 
					
						
							|  |  |  |         if (!props && redirect) { | 
					
						
							|  |  |  |           res.redirect(redirect.pathname + redirect.search); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-13 18:12:22 -07:00
										 |  |  |         if (!props) { | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |           log(`react tried to find ${location.pathname} but got 404`); | 
					
						
							| 
									
										
										
										
											2015-07-03 21:46:22 -07:00
										 |  |  |           return next(); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-13 18:12:22 -07:00
										 |  |  |         return !!props; | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |       .flatMap(({ props, store }) => { | 
					
						
							|  |  |  |         log('render react markup and pre-fetch data'); | 
					
						
							| 
									
										
										
										
											2016-01-03 19:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |         return renderToString( | 
					
						
							| 
									
										
										
										
											2016-03-02 19:45:54 -08:00
										 |  |  |           provideStore(React.createElement(RouterContext, props), store) | 
					
						
							| 
									
										
										
										
											2015-12-22 19:28:07 -08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |           .map(({ markup }) => ({ markup, store })); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |       .flatMap(function({ markup, store }) { | 
					
						
							|  |  |  |         log('react markup rendered, data fetched'); | 
					
						
							|  |  |  |         const state = store.getState(); | 
					
						
							|  |  |  |         const { title } = state.app.title; | 
					
						
							|  |  |  |         res.expose(state, 'data'); | 
					
						
							| 
									
										
										
										
											2015-07-29 10:16:48 -07:00
										 |  |  |         return res.render$( | 
					
						
							|  |  |  |           'layout-react', | 
					
						
							|  |  |  |           { markup, title } | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |       .doOnNext(markup => res.send(markup)) | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       .subscribe( | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |         () => log('html rendered and ready to send'), | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |         next | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-29 12:01:56 -07:00
										 |  |  | } |