How to use .vue files with Rails 5.1 - ruby-on-rails

I currently have one application.js file in my Rails app in which I've put all my Vue.js code, as follows:
import Vue from 'vue/dist/vue.esm';
document.addEventListener('DOMContentLoaded', () => {
if(document.getElementById('dashboard-topbar')) {
const dashboard = new Vue({
... do stuff
})
}
if(document.getElementById('map')) {
const map = new Vue({
... do stuff
})
}
if(document.getElementById('something-else')) {
const something-else = new Vue({
... do stuff
})
}
}
but I would like to separate these into their own .vue files.
What's the recommended way & directory structure for doing this?
Thanks!

You have to make use webpack and you need to configure specific loader for vue file and another supporting loader. By googling itself you can find articles to build vue app from scratch(https://www.google.co.in/search?q=vuejs+webpack+starting).
For directory structure you may follow the vue-cli (https://github.com/vuejs-templates/webpack)

Related

how to use external Javascript library in vaadin?

I want to use an external js library in my vaadin application.
i installed the library with the command npm install #iota/identity-wasm and now it is inside the node_modules folder.
The JS code can also be executed without any problems, which means that the library is installed correctly.
However, if I set the annotation #JsModule("./register.js") in my Java class, Then I get the error message that the external Js-Bib is not found.
the register.js file is in the frontend folder.
this is how my Java class looks now
#Route("")
#NpmPackage(value = "#iota/identity-wasm", version = "0.6.0")
#JsModule("#iota/identity-wasm/node/identity_wasm.js")
#JsModule("./register.js")
public class RegisterView extends VerticalLayout { .... }
this is what i get when i go to localhost
=============================UPDATE=============================
Thanks to the hint from ( Sascha Ißbrücker ) The frontend can now be compiled successfully. but I still can't execute any Js-code( from the #iota/identity-wasm library) in my Vaadin application.
so the js code should be executed when i click on a button.
this is what my Js code looks like, what I want to execute from my Java code
const {AccountBuilder, ExplorerUrl} = require('#iota/identity-wasm/web')
window.register = {
createDid : async function (){
console.log("creating identity... This might take some time to complete POW")
let builder = new AccountBuilder();
let account = await builder.createIdentity();
let did = account.did();
console.log(`Explorer Url:`, ExplorerUrl.mainnet().resolverUrl(did));
return account.document();
}
}
This is what is should happen after I click my Vaadin button (Java-Code)
Button submit = new Button("Submit");
submit.addClickListener(
event -> UI.getCurrent()
.getPage()
.executeJs("return register.createDid()")
.then(s-> System.out.println(s))
);
Should i do anything else in the java code to make this work ??
best regards

Rails 7 + importmap + fullcalendar

I've manage to include bootstrap 5 without any issues, but when I try to include fullcalendar I get this error on browser console:
Failed to load module script: Expected a JavaScript module script but
the server responded with a MIME type of "text/css". Strict MIME type
checking is enforced for module scripts per HTML spec. (main.css:1)
So it looks like the library is imported correctly but the css isn't
my stimulus controller:
import { Controller } from "#hotwired/stimulus"
import moment from "moment"
import { Calendar } from '#fullcalendar/core';
import dayGridPlugin from '#fullcalendar/daygrid';
import timeGridPlugin from '#fullcalendar/timegrid';
import listPlugin from '#fullcalendar/list';
export default class extends Controller {
static targets = [ "calendar" ]
connect() {
console.log(this.calendarTarget)
let calendar = new Calendar(this.calendarTarget, {
plugins: [ dayGridPlugin, timeGridPlugin, listPlugin ],
initialView: 'dayGridMonth',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,listWeek'
}
});
}
}
Any ideias what I'm doing it wrong?
EDIT: looks like is related to:
https://github.com/rails/rails/issues/44239
I have been fiddling with this problem for a while today. I too couldn't get past the issue with the JS trying to pull in the CSS and raising MIME type errors.
However, I have managed to get FullCalendar running with importmaps by vendoring the main.js file provided by the CDN (referenced here), and then manually editing the vendored file to export the FullCalendar function as the default.
main.js -> https://cdn.jsdelivr.net/npm/fullcalendar#5.11.0/main.min.js
Copy this into vendor/javascript/fullcalendar.js
Pin the file in importmap.rb:
pin "fullcalendar" # #5.11.0
At this point I have the following error:
Failed to register controller ... SyntaxError: The requested module 'fullcalendar' does not provide an export named 'default'
Edit your new vendor/javascript/fullcalendar.js file and append to the bottom:
export default FullCalendar;
And then in the stimulus controller:
import { Controller } from "#hotwired/stimulus"
import FullCalendar from 'fullcalendar';
export default class extends Controller {
connect() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth'
});
calendar.render();
}
}
Css is just brought in via application.scss as normal.

How can I use React Hooks with ReactJS.NET?

We are currently migrating our frontend from jQuery to Reactjs.NET. We are using React 16.8 which allows us to use React Hooks instead of classes.
We setup our project successfully and tried it first with classes and server side rendering which worked well, but my team rather use React Hooks. I tried using Webpack + Babel to transpile .jsx files since it didn't work anymore using only razor helper #Html.React(), but I still get the same error from my component.
We are using Asp.NET 4.x and NET framework 4.7.
This is my view children.cshtml
#Html.React("ChildrenForm", new {
familyTiesId = Model.FamilyTiesId
},
serverOnly:true
)
This is my ReactConfig.cs:
namespace Nop.Web
{
public static class ReactConfig
{
public static void Configure()
{
// If you want to use server-side rendering of React components,
// add all the necessary JavaScript files here. This includes
// your components as well as all of their dependencies.
// See http://reactjs.net/ for more information. Example:
ReactSiteConfiguration.Configuration
.AddScript("~/Scripts/Components/Customer/ChildrenForm.jsx");
JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName;
JsEngineSwitcher.Current.EngineFactories.AddV8();
}
}
}
My component:
import React, { useState, useEffect } from 'react';
const ChildrenForm = (props) => {
const [ familyTiesId, setFamilyTiesId ] = useState(props.familyTiesId);
...
}
It should work, but instead I get:
SyntaxError: Unexpected identifier
Line 20: #Html.React("ChildrenForm", new {
Line 21: ddtl = Model.DDTL,
Line 22: listFamilies = Model.ListFamilies,
...
[JsCompilationException: SyntaxError: Unexpected identifier
at ChildrenForm.jsx:6:8 -> import React, { useState, useEffect } from 'react';]
JavaScriptEngineSwitcher.V8.V8JsEngine.InnerExecute(String code, String documentName) +258
React.ReactEnvironment.EnsureUserScriptsLoaded() +548
It seems like we cannot import files when using razor helper #Html.React and server side rendering.
How can I do an import and use React Hooks while server side rendering?
Instead of having to import it, you can just use:
const [ familyTiesId, setFamilyTiesId ] = React.useState(props.familyTiesId);
Just call useState directly instead of importing.

Angular 2 and ActionCable integration

I'm trying to make a Angular2 app (bootstrapped with angular-cli) work with Rails's ActionCable by integrating this lib on the frontend https://github.com/mwalsher/actioncable-js
I npm installed the lib,
added this to angular-cli-build.js
'actioncable-js/index.js',
and this in system-config.ts:
/** Map relative paths to URLs. */
const map: any = {
'moment': 'vendor/moment/moment.js',
'ng2-bootstrap': 'vendor/ng2-bootstrap',
'lodash': 'vendor/lodash',
'actioncable-js': 'vendor/actioncable-js'
};
/** User packages configuration. */
const packages: any = {
'ng2-bootstrap': {
format: 'cjs',
defaultExtension: 'js',
main: 'ng2-bootstrap.js'
},
'actioncable-js':{
main: 'index.js'
},
'moment':{
format: 'cjs'
},
'lodash':{
main: "lodash.js"
}
};
added this to my component:
import { ActionCable } from 'actioncable-js';
but the build errors with this message:
Cannot find module 'actioncable-js'.
anyone has any idea why?
My guess is typings are missing, but I'm not sure how to fix this.
Rails has since released an official actioncable package here:
https://www.npmjs.com/package/actioncable
No there is no problem with typings. What you are missing is how to use Javascript library in angular 2 typescript application. If you want to use JavaScript library in your TypeScript application, then you need to import the library import 'actioncable-js' and then you have to declare the variable. declare let ActionCable:any This tells typescript we have a global variable ActionCable present in our application. Now you can access it in your angular 2 component implementations and do whatever you want to do. You can read the discussion here.
angular-cli.build.js
vendorNpmFiles: ['actioncable-js/**/*.js']
systemjs.config.js
map:{ 'actioncable-js':'vendor/actioncable-js/dist/action_cable.js'}
package:{'actioncable-js': defaultExtension: 'js'} }
`
app.component.ts
import 'actioncable-js';
declare let ActionCable:any;
#Component({
....
})
export class AppComponent implements OnInit{
constructor(){}
ngOnInIt(){
//can access *ActionCable* object here
}
}

RelayQL: Invalid fragment composition

I'm getting Invariant Violation: RelayQL: Invalid fragment composition, use `${Child.getFragment('name')}`. in the following. I've no idea why, and nothing seems to fix it. My component contains:
fragments: {
album: () => Relay.QL`
fragment on Album {
${AlbumMutation.getFragment('album')}
}
`,
},
AlbumMutation contains:
static fragments = {
album: () => Relay.QL`
fragment on Album {
id
}
`,
}
To anybody who runs into this, its probably due to the examples loading the React, Relay, and ReactDOM libs in the public/index.html file, instead of using the webpack import X from 'y';. If you are attempting to use the react-relay-router library, you have to use the latter, but having two copies of Relay will cause this error to occur.
I was able to fix this by removing the references in public/index.html, but its good to know that double-importing relay does seem to break this!
I was able to fix this in ES6 by removing my React/Relay imports from the component.
import React from 'react';
import Relay from 'react-relay';
class ...

Resources