How can I make add firepad to my reactjs project? - javascript

So I've been learning react, and wanted to make a basic firepad instance. My current setup is having one container div in my index.html, and having all of my react components rendering through that div. My current attempts and the code I'm showing with this have been in an environment with gulp and browserify, but I'm also playing around with ES6 and webpack. So I'm pretty flexible about getting this working as I learn. Here's the code:
"use strict"
var React = require('react')
, Firebase = require('firebase')
, fbRoot = 'myURL'
, CodeMirror = require('codemirror')
, Firepad = require('firepad')
, firepadRef = new Firebase(fbRoot + 'session/')
, myCodeMirror = CodeMirror(document.getElementById('firepad'), {lineWrapping: true})
, myFirePad = Firepad.fromCodeMirror(firepadRef, myCodeMirror, { richTextShortcuts: true, richTextToolbar: true, defaultText: 'Hello, World!'});
var WritePage = React.createClass({
render: function(){
return (
<div>
<div id="firepad"></div>
</div>
);
}
});
module.exports = WritePage;
The first error I was getting was that it couldn't find the codemirror.js file. Although CodeMirror was being correctly defined in Chrome's dev tools, I moved that from requiring the npm package to just linking the 2 needed codemirror files to my html. It then gave me an error about not being able to take .replaceChild of undefined. I then tried moving all of the dependency files over to my index.html, but still had the same .replaceChild error. Anyone have any experience with react and firepad? I read in the reactfire docs that it's one way binding from firebase to my site, which for my case making a read-only firepad would be fine. Like I said, I'm flexible all of this stuff is new to me.

From the link that Michael provided.
The problem is that you are trying to reference a DOM element before React has rendered your component.
, myCodeMirror = CodeMirror(document.getElementById('firepad'),{lineWrapping: true})
, myFirePad = Firepad.fromCodeMirror(firepadRef, myCodeMirror, {richTextShortcuts: true, richTextToolbar: true, defaultText: 'Hello, World!'});
By moving this code into componentDidMount(), it runs after the CodeMirror DOM element has been constructed and you'll be able to reference the DOM node. You will also probably find it easier to use the React ref attribute instead of document.getElementById().

Use these npm packages - brace, react-ace, firebase, firepad.
Since firepad needs aceto be present globally, assign brace to global var
like(not the best way, but works) before importing firepad
import firebase from 'firebase/app';
import 'firebase/database';
import brace from 'brace';
global.ace = brace;
global.ace.require = global.ace.acequire;
import Firepad from 'firepad';
Use ref to get instance of ReactAce and initialize it in componentDidMount using:
new Firepad.fromACE(this.firepadRef, this.aceInstance.editor, options);
Similarly for CodeMirror editor.
Hoping, this would be of some help.

Related

Uppy doesn't appear on the screen in rails app

I'm trying to do a very simple app just to test the Uppy file uploader. I've followed the Uppy's documentation, but it just worked with the library links (CDN).
I've already tried npm install #uppy/core (and the same command for the additional plugins). I've already tried to put the code inside my coffee file (I'm using ruby on rails). And other things too, but no results.
Here's my code:
import '#uppy/core/dist/style.css'
import '#uppy/dashboard/dist/style.css'
Uppy = require('uppy/lib/core')
Dashboard = require('uppy/lib/plugins/Dashboard')
uppy = Uppy({ autoProceed: false })
uppy.use(Dashboard, { target: '#drag-drop-area', inline: true })
This is actually throwing no errors, just doesn't appear on the screen.
I just found the answer. It happens that you actually need to use a bundler in order to make the 'require' works in the browser. This is not explicit in uppy's documentation, but I guess I should already know it. Thanks!
In my case I had to add the new keyword when initializing Uppy.
This is from the documentation .
So instead uppy = Uppy({ autoProceed: false }) it should be const uppy = new Uppy({autoProceed: false})
Hope that helps.
P.s I think that is for the new versions of Uppy.

Is it possible to auto import JS files for all react components?

I have created a logging utility function that I plan to use on 99% of components in my site. I am wondering if it is possible to access this file without having to write "import { logger } from 'utils/logging';" for every React component? Sort of like an auto import?
I am using create-react-app.
If I understand your requirement properly, you want the similar usage of console.log (without importing console), then below is something you can try.
In your index file, set it as a global object(for server side js) or window object (for client side js). So that , it can be accessed anywhere.
We had something like this with a mmiddleware(using redux-logger package):
const logger = require('redux-logger').createLogger
return middleware.concat(logger({
collapsed: true,
duration: true
}))
Hope this helps!
What you're trying to do sounds like a bad way to do it. I think the best solution if you need custom data logged, would be to create/add a middleware. Or in React's case maybe a wrapper component. I'm not sure.
Otherwise look into React / Redux Dev Tools Extension.
https://github.com/facebook/react-devtools
https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
Edit:
If you want to ignore good practices then you can do this:
// in index.js or app.js or wherever
import { logger } from 'utils/logging'
// if you have an env for development use it here
process.NODE_ENV = 'development' && window.logger = logger
// or just
window.logger = logger
// SomeComponent.js
window.logger()

Importing javascript file for use within vue component

I am working on a project that requires using a js plugin. Now that we're using vue and we have a component to handle the plugin based logic, I need to import the js plugin file within the vue component in order to initialize the plugin.
Previously, this was handled within the markup as follows:
<script src="//api.myplugincom/widget/mykey.js
"></script>
This is what I tried, but I am getting a compile time error:
MyComponent.vue
import Vue from 'vue';
import * from '//api.myplugincom/widget/mykey.js';
export default {
data: {
My question is, what is the proper way to import this javascript file so I can use it within my vue component?
...
Include an external JavaScript file
Try including your (external) JavaScript into the mounted hook of your Vue component.
<script>
export default {
mounted() {
const plugin = document.createElement("script");
plugin.setAttribute(
"src",
"//api.myplugincom/widget/mykey.js"
);
plugin.async = true;
document.head.appendChild(plugin);
}
};
</script>
Reference: How to include a tag on a Vue component
Import a local JavaScript file
In the case that you would like to import a local JavaScript in your Vue component, you can import it this way:
MyComponent.vue
<script>
import * as mykey from '../assets/js/mykey.js'
export default {
data() {
return {
message: `Hello ${mykey.MY_CONST}!` // Hello Vue.js!
}
}
}
</script>
Suppose your project structure looks like:
src
- assets
- js
- mykey.js
- components
MyComponent.vue
And you can export variables or functions in mykey.js:
export let myVariable = {};
export const MY_CONST = 'Vue.js';
export function myFoo(a, b) {
return a + b;
}
Note: checked with Vue.js version 2.6.10
try to download this script
import * from '{path}/mykey.js'.
or import script
<script src="//api.myplugincom/widget/mykey.js"></script>
in <head>, use global variable in your component.
For scripts you bring in the browser way (i.e., with tags), they generally make some variable available globally.
For these, you don't have to import anything. They'll just be available.
If you are using something like Webstorm (or any of the related JetBrains IDEs), you can add /* global globalValueHere */ to let it know that "hey, this isn't defined in my file, but it exists." It isn't required, but it'll make the "undefined" squiggly lines go away.
For example:
/* global Vue */
is what I use when I am pulling Vue down from a CDN (instead of using it directly).
Beyond that, you just use it as you normally would.
I wanted to embed a script on my component and tried everything mentioned above, but the script contains document.write. Then I found a short article on Medium about using postscribe which was an easy fix and resolved the matter.
npm i postscribe --save
Then I was able to go from there. I disabled the useless escape from eslint and used #gist as the template's single root element id:
import postscribe from 'postscribe';
export default {
name: "MyTemplate",
mounted: function() {
postscribe(
"#gist",
/* eslint-disable-next-line */
`<script src='...'><\/script>`
);
},
The article is here for reference:
https://medium.com/#gaute.meek/how-to-add-a-script-tag-in-a-vue-component-34f57b2fe9bd
For anyone including an external JS file and having trouble accessing the jQuery prototype method(s) inside of the loaded script.
Sample projects I saw in vanilla JS, React and Angular were simply using:
$("#someId").somePlugin(options)
or
window.$("#someId").somePlugin(options)
But when I try either of those in my VueJS component I receive:
Error: _webpack_provided_window_dot$(...).somePluginis not a function
I examined the window object after the resources had loaded I was able to find the jQuery prototype method in the window.self read-only property that returns the window itself:
window.self.$("#someId").somePlugin(options)
Many examples show how to load the external JS file in VueJS but not actually using the jQuery prototype methods within the component.

Bundle and use in another file

I want use material-ui.com in my react site.But i cant understand how add to my asp.net site.
I bundle with browserify.But i cant use it in my other pages.I take error in console
Uncaught TypeError: Cannot read property 'toUpperCase' of undefined .
var CalisanIslemListesi = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
render:function(){
return (<p><RaisedButton /></p>);
}
});
My bundle file http://www.filedropper.com/materialuibundle
This was a very common problem for me too. This happens because MaterialUI needs some basic styles in order to work. You can find them here: http://material-ui.com/#/get-started
So unless you add these style to all components that use material-ui, it'll show the above error because it is looking for a dependency that is not available. If you go to the link above, it'll show you what styles it needs. However, it becomes very tedious to include those styles everytime, in every component that I make.
I use React Mixins. They're BASICALLY partial components that you can add to your component code. When you add a mixin to a component, what effectively happens is, the mixin gets expanded and added to your component. A lot like variables in string concatenation (Horrible example, I know, but it'll help you understand). When you add a variable to a string concatenation, the variable effectively gets replaced by its value. That is what happens with React Mixins.
Here is what I like to do:
Define a material.jsx file in my directory that goes like this (It is basically copied from their getting started page):
var React = require('react'),
mui = require('material-ui'),
ThemeManager = new mui.Styles.ThemeManager(),
injectTapEventPlugin = require("react-tap-event-plugin");
injectTapEventPlugin();
module.exports = {
childContextTypes: {
muiTheme: React.PropTypes.object
},
getChildContext: function() {
return {
muiTheme: ThemeManager.getCurrentTheme()
};
}
}
The above is just a mixin, it contains all styles required by Material-UI to function properly.
Now I'll just use the above module as a mixin in all Material-UI components.
var React = require('react'),
material = require('./material.jsx'),
mui = require('material-ui'),
FlatButton = mui.FlatButton
module.exports = React.createClass({
mixins: [material],
render: function() {
return <FlatButton>Hello</FlatButton>
}
})
In your code, if you make this material.jsx file and add the line mixins: [material] like I did, it'll all start working :)

Browserify and Vue: uncaught reference error: Vue is not defined

This is my first foray into any front-end development beyond basic jQuery stuff, and I'm using Vue.js along with some other packages with Browserify. My main 'app.js' looks like this:
window.$ = window.jQuery = require('jquery');
require('bootstrap');
var moment = require('moment');
var fullCalendar = require('./vendor/fullcalendar.min.js');
var datetimepicker = require('./vendor/bootstrap-datetimepicker.min.js');
var select2 = require('./vendor/select2.min.js');
var VueResource = require('vue-resource');
var Vue = require('vue');
require('./videos/show.js');
require('./home.js');
require('./search.js');
Vue.use(VueResource);
new Vue({
el: '#search',
data: {
message: 'Hello World!'
},
});
...
It works as expected this way, but when I try to create a new Vue instance in another file (in search.js, for instance) I can't do it. I get the 'Uncaught reference error: Vue is not defined' in my console. No problem with using the other required packages elsewhere - although I don't understand why I need to import jQuery the way I'm doing it... it won't work if I do:
var $, jQuery = require('jquery');
I'm sure this is something very basic and fundamental that I am not understanding yet but any help would be greatly appreciated!
The problem you are having is the basics of using modules. In general, a module should always export some behavior or property and then you require that module and use it. For example, say I wanted to add a hidden into to a form on some pages. I would do this:
AddSecretToken.js
module.exports = function(form) {
// code here to add the hidden input to the passed in form
}
Then somewhere else where I had a form that needed the secret input, I would require it:
MyForm.js
var addSecretToken = require('./AddSecretToken');
...
// some code that makes a form
addSecretToken(myForm);
...
Obviously, at some point you need some code that actually runs something but that would be your root module or the page where you require the root module. So maybe you have an app.js at the top and it requires what it needs and then runs app() without exporting anything. That makes sense. But the majority of modules shouldn't be doing that.
Any time you need some behavior, you should make a module and then anywhere you need the behavior, you require the module. Each module should require what it depends on -- it shouldn't depend on any global (sometimes jQuery is an exception).

Categories

Resources