How to embed a React starterkit app into legacy Rails app? - ruby-on-rails

I have a React app based on the starterkit of Erik Rasmussen from here.
The app works pretty well, using React Router and Redux.
Since my Rails app is pretty old, the idea to embed the application, is to have a separate controller where the index action renders an iFrame, which itself loads it's content from the same controllers show action.
Therefore I can stick with my Rails app's layout, and have the React apps markup rendered w/o any changes.
After I transpiled the app via
$> npm run build
I copy the main-.js and main-.css files into the Rails app, so they can be delivered from there.
Afterwards I start the React app via:
$> npm run start
and request the starting page via curl. The curl output goes into my show erb template. Inside I change the URL's where the main JS and CSS is loaded from.
When I request my index page now, the iFrame loads it's content, the app seems to initialize, but does not work at all. I see rendered content, but clicking on links leads to Rails routing errors. So the clicks seem not to be intercepted by React.
I tried to track execution down, and ended up debugging the code in client.js. It seems like, ReactDOM.render receives proper arguments, meaning, there is a proper looking component to render, a store, and even the destination element.
Currently I get the following error in the console:
Uncaught ReferenceError: _classCallCheck is not defined
I am using a slightly oder version of the starterkit, which embeds initial data into the markup, but I was not able to figure out, why the _classCallCheck works in the React app, but stops working, when embedded into Rails.
Even the most recent version of the starterkit does not work either. In that case I do not get any error at all, but have the same behavior.
Due to the old Rails version I can not use the React Gem, and I need some of the functionality the starterkit provides out of the box, so changing this one, is no option either.
Any hints?

Related

Vaadin / load reactjs build

We develop a reactjs application which works fine, but one of our customer wants to load this application inside their vaadin environment.
I thought sending them the reactjs build will be enough but for some reason they cannot load it : they use vaadin 14 and try to load the build script via #JsModule annotation and put a vaadin div component with the correct id (in order for reactjs to bootstrap it) but they say they hava this error :
Uncaught Error: Minified React error #200; visit
https://reactjs.org/docs/error-decoder.html?invariant=200 for the full
message or use the non-minified dev environment for full errors and
additional helpful warnings
I dont know what's is going on here.
Thanks
If you follow that link, you'll see that the full error message is:
Target container is not a DOM element.
It seems likely that when the script ran, the target Div did not exist yet. Using #JsModule means that the Vaadin application will include that module into its Javascript build, and run it as soon as the Vaadin application bootstraps in the browser. At that point in time there isn't anything related to the Vaadin application in the DOM yet.
One thing you could try is to change your script to expose a function (for example using a window global) to render the React application into the Div, rather than have the script render the React application immediately when the script runs. On the Vaadin side, your customer could then call that function as soon as the target Div has been added to the DOM, for example using executeJs in the components onAttach method.

VueJS With Multi-Page Rails 6 App With Turbolinks - Layout

I've got a specific question that I'm struggling to find information online for. I've successfully installed VueJS into my Rails 6 app using webpacker and have a root component registering just fine on my application layout file:
<!-- application.html.erb -->
<!-- javascript pack tags loaded in head and my app component displays the template properly -->
<div id="vue-app-root">
<app></app>
</div>
I'm aware that in a single-page app, the VueJS app initializes a single time upon visiting the website and then async requests are made and view/template changes are initiated by VueJS - all makes sense. My question pertains to how exactly the vue app initialization should work with a multi-page app.
Does the app initialize completely on every reload/turbolink load? If I'm just using a few components here and there in various pages, am I stuck with having the entire VueJS app initialize on each page load and then, subsequently, the components? If so, should I have the Vue JS app initialize on the body tag (or a root element) within the application.html.erb or should I have the app initialize only on the pages that have components?
You need to find out what is responsible for your routing - Vue or Rails?
If it is Rails, then yes, Vue app will need to be remounted on every page load. This applies whether or not you use Turbo/Turbolinks, as long as Vue app is in the fetched partial. If the fetched partial is outside the Vue container and you use Turbo/Turbolinks, Vue app will not be reloaded. This is true even for a server rendered Vue which hydrates on client.
If it is Vue that does the routing, Rails may not do it, otherwise Vue app will always be reloaded.
To #sjaustirni's answer, I'd add that depending if you want to use Rails integrated routing or not, you may split the 2 codebases. What I mean: if you do only use Rails as an API and not it's routing, you should put the Vue project in it's own repo rather than mixing both.
Of course if you're using Rails' routing, it makes sense to keep both in the same place.
Also, I would like to share the existence of vue-turbolinks which may be useful in your case, especially if using Hotwire.
Here is a video explaining it: https://gorails.com/episodes/how-to-use-vuejs-and-turbolinks-together

Angular2 routing views not rendering properly with polymer (on mobile) using back and forward buttons

I am building a basic Angular2 + Polymer seed application (as well as rebuilding personal site), when testing it out on mobile I ran into a few problems. I am using the Router supplied by angular2/router and have inserted a <script src="webcomponents.js_here"></script> to include webcomponents.js after angular 2.0.0-beta.7 (as I write) has been pulled in.
Simplest example I could boil it down to is reproducing the error in the Angular2 Hero tutorial. If you check this plnkr out on a mobile browser you will see that when you navigate from one view, to another and you try to go back to the previous view relying on window.history.back() as the ng2 tutorial does, you will be able to go back to the previous views but at the following costs:
The view is not loaded properly
constructor() gets called but ngInit() never gets called
If you move the service-fetching logic from ngInit() to the constructor (as I did in the plunk) to test to see if the service data is still being fetched properly, the view is still not rendered properly (makes me think there is some polyfill conflict issue stopping the structural directives (*ngFor in this case) from working and manipulating the DOM properly. To get the view to load properly and the structural directives to work again with the service fetched data, you have to navigate to that view in any other way but using the window.history. This makes natural Back/Forward button routing an issue in Angular2 apps that use Polymer. It seems that as of posting this it only happens on mobile browsers.
I am testing on an iPhone 6 plus iOS 9 (9.2) and Chrome version 48.0.2564.104
Could this be some sort of view caching or polyfill problem?

Google Analytics MIME type issue in Chrome using Rails 3

I'm adding GA to a Rails 3 app, which would normally be extremely simple, of course. I've added the GA JS snippet, which is rendering just fine. Everything works perfectly in Safari. In Chrome, however, it's giving me a console error: Resource interpreted as Script but transferred with MIME type text/html: "about:blank", pointing to the JS line that loads the ga.js file: s.parentNode.insertBefore(ga, s). Some things I've investigated:
I created a plan HTML page with the JS snippet, and it loads outside Rails in Chrome with no error.
The same HTML page, when put in /public, gives the error above.
The same HTML page, loaded in Safari from /public, doesn't give any error according to Firebug.
I tried the GA Debug extension in Chrome, but it remains silent, because ga.js isn't getting loaded.
Looking at the developer console in Chrome, I see a request for "http://www.google-analytics.com/ga.js" that seems to stay in "pending" state, and a redirect to "about:blank" seemingly initiated by http://www.google-analytics.com/ga.js, which makes very little sense.
So this seems to be related to Rails (since the snippet works in the HTML outside Rails), and doesn't affect Safari, but other than that I'm stumped. Hopefully I've just been staring at it wrong, and someone else will point out the obvious to me...? Anyone come across this before? Any ideas will be very much appreciated.
Came across this issue myself. "Disconnect" disabled share buttons on my site (g+, twitter and fb). Had to remove it to view the site properly.

Rails 3 Links are broken after activescaffold update

I just updated active scaffold on my rails app, and now all the links are broken on the site. If I hover over the link in firefox, I can see http://localhost:3000/correct_link; however, when I click the link, I end up at http://localhost:3000/current_link#__1_. When the link is loaded all styling/javascript is messed up. Furthermore, the number after the two underscores increases every time I click another link, but I can never navigate away from http://localhost:3000/current_link__NUM_.
Interestingly, if I type the url that I want into the browser, all is well. There don't seem to be any errors in my logs or in my server console.
I'm not sure how to go about debugging this
Aha! The error was caused by my removing active_scaffold, which introduced some weird behavior from custom javascript that had hooked into it. After active scaffold was removed, the javascript started hijacking the links. Shuffling the javascript around fixed the bug

Resources